1

It's possible to create good visualization graphs with Visualization API + Highcharts library but it seems overriding the chart options is not possible.

Highcharts API has tons of options such as (http://api.highcharts.com/highcharts#xAxis.tickInterval).

I want to set options for some charts not for all of them.

I created a views and visualize it. It's OK. I made some changes on highcharts.inc (modules/visualization/includes/plugins/highcharts.inc).

if (!empty($x_axis)) {
  $highchart->xAxis = (object) array(
    'categories' => $x_axis,
    'tickInterval' => "10",

  );
}


I added the 'tickInterval' => "10", line and it's working... but it's working for all charts. I want to set this options for only some charts. Is there a way to do this by for example adding a if clause with the views name I wanted to set the options?

I tried to add a line to the file ( if ($view->name == 'myview') { )

if ($view->name == 'myview') {
if (!empty($x_axis)) {
  $highchart->xAxis = (object) array(
    'categories' => $x_axis,
    'tickInterval' => "1",

  );
}
}


But it gives error as I expected: Undefined variable: view

Yes, here how could I made the highcharts.inc file understand the view variables or is there any other way to do this?

EDITED (the highcharts.inc is below ):

<?php
/**
 * @file
 * Library plugin for Visualization implementing support for Highcharts.
 */

class HighchartsHandler implements VisualizationHandlerInterface {

  protected $addedJavascript = FALSE;
  protected $available = FALSE;

  /**
   * Constructor for the Highcharts plugin.
   */
  public function __construct() {
    if (module_exists('libraries')) {
      module_load_include('module', 'libraries', 'libraries');
      $path = libraries_get_path('highcharts');

      $this->available = is_dir('./' . $path);
    }
  }

  /**
   * Renders a chart using Highcharts.
   */
  public function render($chart_id, $data, $options) {
    // Chart options.
    $highchart = new stdClass();

    // Chart.
    $highchart->chart = (object) array(
      'plotBackgroundColor' => NULL,
      'plotBorderWidth' => NULL,
      'plotShadow' => FALSE,
    );

    // Set title.
    $highchart->title = new stdClass();
    $highchart->title->text = $options['title'];

    $x_axis = array();
    if (!empty($options['xAxis']['labelField'])) {
      foreach ($data as $row) {
        $x_axis[] = check_plain(strip_tags((string) $row[$options['xAxis']['labelField']]));
      }
    }

    if (!empty($x_axis)) {
      $highchart->xAxis = (object) array(
        'categories' => $x_axis,
        'tickInterval' => "10",

      );
    }


    if ($view->name == 'myview') {
    if (!empty($x_axis)) {
      $highchart->xAxis = (object) array(
        'categories' => $x_axis,
        'tickInterval' => "1",

      );
    }
    }






    if (!empty($options['yAxis']['title'])) {
      $highchart->yAxis = (object) array(
        'title' => (object) array(
          'text' => $options['yAxis']['title'],
        ),
        'min' => "0", 
      );
    }

    // Series.
    $highchart->series = array();
    foreach ($options['fields'] as $name => $column) {
      if (!empty($column['enabled'])) {
        $serie = new stdClass();
        $serie->name = $column['label'];
        $serie->type = $options['type'];

        $serie->data = array();
        foreach ($data as $row) {
          $value = (int) $row[$name];

          if (!empty($column['enabled'])) {
            $serie->data[] = (object) array('name' => check_plain(strip_tags($row[$options['xAxis']['labelField']])), 'y' => $value);
          }
          else {
            $serie->data[] = $value;
          }
        }

        $highchart->series[] = $serie;
      }
    }

    $highchart->plotOptions = new stdClass();
    $highchart->plotOptions->pie = (object) array(
      'allowPointSelect' => TRUE,
      'cursor' => 'pointer',
      'dataLabels' => (object) array(
        'enabled' => TRUE,
        'format' => "<b>{point.name}</b>: % {point.percentage:.1f}"
      ),
      'showInLegend' => TRUE,
    );
    $highchart->plotOptions->bar = (object) array(
      'dataLabels' => (object) array(
        'enabled' => TRUE,
      ),
    );

    $highchart->credits = new stdClass();
    $highchart->credits->enabled = FALSE;

    // Rendering.
    $highchart->chart->renderTo = $chart_id;

    $information = array(
      'library' => 'highcharts',
      'options' => $highchart,
    );

    // Add Drupal.settings for this chart.
    drupal_add_js(array('visualization' => array($chart_id => $information)), array('type' => 'setting'));
  }

  /**
   * Includes global Javascript required by Highcharts.
   */
  public function postRender() {
    if (!$this->addedJavascript) {
      module_load_include('module', 'libraries', 'libraries');
      $path = libraries_get_path('highcharts');
      drupal_add_js($path . '/js/highcharts.js');

      drupal_add_js(drupal_get_path('module', 'visualization') . '/js/highcharts.js', array('scope' => 'footer'));

      $this->addedJavascript = TRUE;
    }
  }

  /**
   * Whether or not the plugin is avialable.
   */
  public function available() {
    return $this->available;
  }

  /**
   * Returns an array with supported chart types.
   */
  public function supportedTypes() {
    return array('line', 'column', 'pie');
  }

}

$plugin = array(
  'name' => 'highcharts',
  'label' => t('Highcharts'),
  'handler' => new HighchartsHandler(),
);
2
  • Hello and welcome. You posted a piece of code with absolutely no context. For example, why did you expect $view to be defined? If function is short enough, post it. If it's too long, tell us what you found about the issues you encountered, and maybe link to API page with it's whole code. Don't expect us to guess / look for places you changes and re-cerate it on our own for you...
    – Mołot
    Commented Nov 13, 2014 at 10:47
  • Thanks @Mołot. I thought it was too long to post but I edited the question and added the whole code. (I didn't expect anybody to re-create the code for me). I don't expect $view to be defined but I want to define it because I need to use the $view->view_name to set the options for each views block.
    – herci
    Commented Nov 13, 2014 at 12:38

1 Answer 1

2

A few points on this:

  1. I recommend not hacking drupal modules like that. You will quite possibly cause yourself troubles later on .
  2. There are patches in the issue queue that allow you to better override charts without hacking the module. See https://www.drupal.org/node/1809850
  3. It may be worth checking out other patches in the issue queue. There are a bunch of patches in there that are useful... which brings me to the most important point:
  4. I would personally recommend not using the visualization module because it is not very actively maintained. In my experience you need a lot of patches and even then there are issues. I recommend instead using the charts module, which has better support for overriding charts and is more actively maintained.
7
  • Thanks for your message @rooby. 1. Yes, you're right, I'm in trouble with this now. 2-3. I have already apllied these patches but didn't work for me. 4. I'm using charts module in another Drupal website but unfortunately this module doesn't fulfill what I need. I'm working on it.
    – herci
    Commented Nov 18, 2014 at 13:04
  • This is a little off topic but out of curiosity, what do you need that the charts module cannot do?
    – rooby
    Commented Nov 19, 2014 at 0:14
  • I want to add tickInterval to some of my charts (api.highcharts.com/highstock#xAxis.tickInterval). Is there any way to do this, you know?
    – herci
    Commented Nov 19, 2014 at 19:03
  • Yes you can override any part of the chart definition. If you look in the module in the charts.api.php file there are a bunch of hooks you can use to modify charts. The hook hook_chart_definition_alter() allows you to override pretty much anything. In that file is a small example of how to use it.
    – rooby
    Commented Nov 19, 2014 at 22:51
  • Yes, this is exactly what I'm looking for. I don't want to modify settings (properties) for all charts, only for some of them, I think I should use that one (function hook_chart_alter): ` /** * Alter an individual chart before it is printed. * function hook_chart_alter(&$chart, $chart_id) { if ($chart_id === 'view_name__display_name') { // Individual properties may be modified. $chart['#title_font_size'] = 20; } }` Should I directly add the codes into charts.api.php or is there any other better way?
    – herci
    Commented Nov 20, 2014 at 10:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.