From 0aaab0c294b3d54b27898842c36b0bbdfb452369 Mon Sep 17 00:00:00 2001
From: Nathan Haug <nate@lullabot.com>
Date: Tue, 22 Apr 2014 19:52:04 -0700
Subject: [PATCH] Issue #2247551 by eneko1907: Clean examples.

---
 includes/charts.examples.inc                  |  2 -
 js/charts.admin.js                            | 42 +++++++++-
 .../charts_highcharts/charts_highcharts.inc   | 20 +++++
 views/charts.views.inc                        |  2 +-
 views/charts_plugin_style_chart.inc           | 84 +++++++++++++------
 5 files changed, 117 insertions(+), 33 deletions(-)

diff --git a/includes/charts.examples.inc b/includes/charts.examples.inc
index 8cd56dd..c4f423c 100644
--- a/includes/charts.examples.inc
+++ b/includes/charts.examples.inc
@@ -11,8 +11,6 @@ function charts_examples($library = NULL, $id = NULL) {
   else {
     $charts_info = charts_info();
   }
-  $output = array();
-
   $table = array();
   foreach ($charts_info as $library => $chart_library_info) {
     $table['header'][] = array(
diff --git a/js/charts.admin.js b/js/charts.admin.js
index af61652..86c188a 100644
--- a/js/charts.admin.js
+++ b/js/charts.admin.js
@@ -7,7 +7,7 @@
 Drupal.behaviors.chartsAdmin = {};
 Drupal.behaviors.chartsAdmin.attach = function(context, settings) {
   // Change options based on the chart type selected.
-  $(context).find('.form-radios.chart-type-radios').once('charts-axis-inverted-processed', function() {
+  $(context).find('.form-radios.chart-type-radios').once('charts-axis-inverted', function() {
 
     // Manually attach collapsible fieldsets first.
     if (Drupal.behaviors.collapse) {
@@ -19,6 +19,8 @@ Drupal.behaviors.chartsAdmin.attach = function(context, settings) {
 
     $(this).find('input:radio').change(function() {
       if ($(this).is(':checked')) {
+        var groupingField = $(this).closest('form').find('.charts-grouping-field').val();
+
         // Flip X/Y axis fieldset labels for inverted chart types.
         if ($(this).attr('data-axis-inverted')) {
           $('fieldset.chart-xaxis .fieldset-title').html(yAxisLabel);
@@ -47,8 +49,14 @@ Drupal.behaviors.chartsAdmin.attach = function(context, settings) {
         else {
           $('fieldset.chart-xaxis').show();
           $('fieldset.chart-yaxis').show();
-          $('th.chart-field-color, td.chart-field-color').show();
-          $('div.chart-colors').hide();
+          if (groupingField) {
+            $('th.chart-field-color, td.chart-field-color').hide();
+            $('div.chart-colors').show();
+          }
+          else {
+            $('th.chart-field-color, td.chart-field-color').show();
+            $('div.chart-colors').hide();
+          }
         }
       }
     });
@@ -57,8 +65,34 @@ Drupal.behaviors.chartsAdmin.attach = function(context, settings) {
     $(this).find('input:radio:checked').triggerHandler('change');
   });
 
+  // React to the setting of a group field.
+  $(context).find('.charts-grouping-field').once('charts-grouping', function() {
+    $(this).change(function() {
+      $form = $(this).closest('form');
+
+      // Hide the entire grouping field row, since no settings are applicable.
+      var value = $(this).val();
+      $form.find('#chart-fields tr').show();
+      if (value) {
+        var $labelField = $form.find('.chart-label-field input[value="' + value + '"]');
+        $labelField.closest('tr').hide();
+        if ($labelField.is(':checked')) {
+          $form.find('input[name="style_options[label_field]"][value=""]').attr('checked', 'checked').triggerHandler('change');
+        }
+      }
+      // Restripe the table after hiding/showing rows.
+      $form.find('#chart-fields tr:visible')
+        .removeClass('odd even')
+        .filter(':even').addClass('odd').end()
+        .filter(':odd').addClass('even');
+
+      // Recalculate shown color fields by triggering the chart type change.
+      $form.find('.form-radios.chart-type-radios input:radio:checked').triggerHandler('change');
+    }).triggerHandler('change');
+  });
+
   // Disable the data checkbox when a field is set as a label.
-  $(context).find('td.chart-label-field input').once('charts-axis-inverted-processed', function() {
+  $(context).find('td.chart-label-field input').once('charts-axis-inverted', function() {
     var $radio = $(this);
     $radio.change(function() {
       if ($radio.is(':checked')) {
diff --git a/modules/charts_highcharts/charts_highcharts.inc b/modules/charts_highcharts/charts_highcharts.inc
index 0aaacc9..d63f226 100644
--- a/modules/charts_highcharts/charts_highcharts.inc
+++ b/modules/charts_highcharts/charts_highcharts.inc
@@ -115,6 +115,11 @@ function _charts_highcharts_populate_chart_options($chart, $chart_definition) {
   $chart_definition['chart']['height'] = $chart['#height'] ? $chart['#height'] : NULL;
   $chart_definition['credits']['enabled'] = FALSE;
 
+  // Merge in chart raw options.
+  if (isset($chart['#raw_options'])) {
+    $chart_definition = drupal_array_merge_deep($chart_definition, $chart['#raw_options']);
+  }
+
   return $chart_definition;
 }
 
@@ -169,6 +174,11 @@ function _charts_highcharts_populate_chart_axes($chart, $chart_definition) {
         }
       }
 
+      // Merge in axis raw options.
+      if (isset($chart[$key]['#raw_options'])) {
+        $axis = drupal_array_merge_deep($axis, $chart[$key]['#raw_options']);
+      }
+
       $chart_definition[$axisType][] = $axis;
     }
   }
@@ -247,6 +257,11 @@ function _charts_highcharts_populate_chart_data(&$chart, $chart_definition) {
       charts_trim_array($series);
       $series['data'] = $series_data;
 
+      // Merge in series raw options.
+      if (isset($chart[$key]['#raw_options'])) {
+        $series = drupal_array_merge_deep($series, $chart[$key]['#raw_options']);
+      }
+
       // Add the series to the main chart definition.
       $chart_definition['series'][$key] = $series;
 
@@ -293,6 +308,11 @@ function _charts_highcharts_populate_chart_data(&$chart, $chart_definition) {
           $series_point['states']['hover']['fillColor'] = $data_item['#color'];
           $series_point['states']['select']['fillColor'] = $data_item['#color'];
           charts_trim_array($series_point);
+
+          // Merge in point raw options.
+          if (isset($data_item['#raw_options'])) {
+            $series_point = drupal_array_merge_deep($series_point, $data_item['#raw_options']);
+          }
         }
       }
 
diff --git a/views/charts.views.inc b/views/charts.views.inc
index eaf21a2..fdddb14 100644
--- a/views/charts.views.inc
+++ b/views/charts.views.inc
@@ -20,7 +20,7 @@ function charts_views_plugins() {
     'uses row class' => FALSE,
     'uses fields' => TRUE,
     'uses options' => TRUE,
-    'uses grouping' => FALSE,
+    'uses grouping' => TRUE,
     'type' => 'normal',
   );
   $plugins['style']['chart_extension'] = $plugins['style']['chart'];
diff --git a/views/charts_plugin_style_chart.inc b/views/charts_plugin_style_chart.inc
index 756e186..2e45b5f 100644
--- a/views/charts_plugin_style_chart.inc
+++ b/views/charts_plugin_style_chart.inc
@@ -46,6 +46,19 @@ class charts_plugin_style_chart extends views_plugin_style {
       return;
     }
 
+    // Limit grouping options (we only support one grouping field).
+    if (isset($form['grouping'][0])) {
+      $form['grouping'][0]['field']['#title'] = t('Grouping field');
+      $form['grouping'][0]['field']['#description'] = t('If grouping by a particular field, that field will be used to generate multiple data series on the same chart.');
+      $form['grouping'][0]['field']['#attributes']['class'][] = 'charts-grouping-field';
+      // Grouping by rendered version has no effect in charts. Hide the options.
+      $form['grouping'][0]['rendered']['#access'] = FALSE;
+      $form['grouping'][0]['rendered_strip']['#access'] = FALSE;
+    }
+    if (isset($form['grouping'][1])) {
+      $form['grouping'][1]['#access'] = FALSE;
+    }
+
     // Merge in the global chart settings form.
     module_load_include('inc', 'charts', 'includes/charts.pages');
     $field_options = $this->display->handler->get_field_labels();
@@ -171,14 +184,16 @@ class charts_plugin_style_chart extends views_plugin_style {
         $data_row = array();
         if ($label_field_key) {
           // Labels need to be decoded, as the charting library will re-encode.
-          $data_row[] = htmlspecialchars_decode($renders[$row_number][$label_field_key], ENT_QUOTES);
+          $data_row[] = htmlspecialchars_decode($this->get_field($row_number, $label_field_key), ENT_QUOTES);
         }
+        $value = $this->get_field($row_number, $data_field_key);
         // Convert empty strings to NULL.
-        if ($renders[$row_number][$data_field_key] === '') {
+        if ($value === '') {
           $value = NULL;
         }
+        // Strip thousands placeholders if present, then cast to float.
         else {
-          $value = (float) $renders[$row_number][$data_field_key];
+          $value = (float) str_replace(array(',', ' '), '', $value);
         }
         $data_row[] = $value;
         $data[] = $data_row;
@@ -207,33 +222,50 @@ class charts_plugin_style_chart extends views_plugin_style {
         '#max' => $this->options['yaxis_max'],
         '#min' => $this->options['yaxis_min'],
       );
-      foreach ($data_fields as $field_key => $field_handler) {
-        $chart[$this->view->current_display . '__' . $field_key] = array(
-          '#type' => 'chart_data',
-          '#data' => array(),
-          '#color' => isset($this->options['field_colors'][$field_key]) ? $this->options['field_colors'][$field_key] : NULL,
-          '#title' => $field_handler->options['label'],
-          '#prefix' => $this->options['yaxis_prefix'] ? $this->options['yaxis_prefix'] : NULL,
-          '#suffix' => $this->options['yaxis_suffix'] ? $this->options['yaxis_suffix'] : NULL,
-          '#decimal_count' => $this->options['yaxis_decimal_count'] ? $this->options['yaxis_decimal_count'] : NULL,
-        );
-      }
 
-      $renders = $this->render_fields($this->view->result);
-      foreach ($renders as $row_number => $row) {
-        if ($label_field_key) {
-          $chart['xaxis']['#labels'][] = $renders[$row_number][$label_field_key];
-        }
+      $sets = $this->render_grouping($this->view->result, $this->options['grouping'], TRUE);
+      foreach ($sets as $series_label => $data_set) {
+        $series_index = isset($series_index) ? $series_index + 1 : 0;
+        $series_key = $this->view->current_display . '__' . $field_key . '_' . $series_index;
         foreach ($data_fields as $field_key => $field_handler) {
-          // Convert empty strings to NULL.
-          if ($renders[$row_number][$field_key] === '') {
-            $value = NULL;
+          $chart[$series_key] = array(
+            '#type' => 'chart_data',
+            '#data' => array(),
+            // If using a grouping field, inherit from the chart level colors.
+            '#color' => ($series_label === '' && isset($this->options['field_colors'][$field_key])) ? $this->options['field_colors'][$field_key] : NULL,
+            '#title' => $series_label ? $series_label : $field_handler->options['label'],
+            '#prefix' => $this->options['yaxis_prefix'] ? $this->options['yaxis_prefix'] : NULL,
+            '#suffix' => $this->options['yaxis_suffix'] ? $this->options['yaxis_suffix'] : NULL,
+            '#decimal_count' => $this->options['yaxis_decimal_count'] ? $this->options['yaxis_decimal_count'] : NULL,
+          );
+        }
+
+        // Grouped results come back indexed by their original result number
+        // from before the grouping, so we need to keep our own row number when
+        // looping through the rows.
+        $row_number = 0;
+        foreach ($data_set['rows'] as $result_number => $row) {
+          if ($label_field_key && !isset($chart['xaxis']['#labels'][$row_number])) {
+            $chart['xaxis']['#labels'][$row_number] = $this->get_field($result_number, $label_field_key);
           }
-          // Strip thousands placeholders if present, then cast to float.
-          else {
-            $value = (float) str_replace(array(',', ' '), '', $renders[$row_number][$field_key]);
+          foreach ($data_fields as $field_key => $field_handler) {
+            // Don't allow the grouping field to provide data.
+            if (isset($this->options['grouping'][0]['field']) && $field_key === $this->options['grouping'][0]['field']) {
+              continue;
+            }
+
+            $value = $this->get_field($result_number, $field_key);
+            // Convert empty strings to NULL.
+            if ($value === '') {
+              $value = NULL;
+            }
+            // Strip thousands placeholders if present, then cast to float.
+            else {
+              $value = (float) str_replace(array(',', ' '), '', $value);
+            }
+            $chart[$series_key]['#data'][] = $value;
           }
-          $chart[$this->view->current_display . '__' . $field_key]['#data'][] = $value;
+          $row_number++;
         }
       }
     }
-- 
GitLab