From a810cd1de0a177fb90d9ea853859aaeab5e35b2a Mon Sep 17 00:00:00 2001 From: Nathan Haug <nate@quicksketch.org> Date: Thu, 25 Jul 2013 22:57:09 -0700 Subject: [PATCH] Issue #2050871: Make the Views preview work. --- charts.module | 22 +++++++++++- modules/charts_google/charts_google.inc | 23 +++---------- modules/charts_google/charts_google.js | 18 ++++++---- modules/charts_google/charts_google.module | 13 +------ .../charts_highcharts/charts_highcharts.inc | 19 ++--------- .../charts_highcharts/charts_highcharts.js | 10 +++--- .../charts_highcharts.module | 11 ------ views/charts_plugin_style_chart.inc | 34 ++++++++++++++----- 8 files changed, 72 insertions(+), 78 deletions(-) diff --git a/charts.module b/charts.module index add1d3e..3d3392d 100644 --- a/charts.module +++ b/charts.module @@ -174,6 +174,9 @@ function charts_theme() { 'charts_settings_fields' => array( 'render element' => 'element', ), + 'charts_chart' => array( + 'render element' => 'element', + ), ); } @@ -226,6 +229,9 @@ function charts_pre_render_element($element) { // Convert integer properties to save library modules the hassle. charts_cast_element_integer_values($element); + // Generic theme function assuming it will be suitable for most chart types. + $element['#theme'] = 'charts_chart'; + // Include the library specific file and render via their callback. if (isset($chart_library_info['file'])) { $module_path = drupal_get_path('module', $chart_library_info['module']); @@ -378,7 +384,21 @@ function charts_cast_element_integer_values(&$element) { charts_cast_element_integer_values($element[$property_name]); } elseif ($property_name && in_array($property_name, $integer_options)) { - $element[$property_name] = is_null($element[$property_name]) ? NULL : (int) $element[$property_name]; + $element[$property_name] = (is_null($element[$property_name]) || strlen($element[$property_name]) === 0) ? NULL : (int) $element[$property_name]; } } } + + +/** + * Output the chart renderable as a string. + */ +function theme_charts_chart($variables) { + $element = $variables['element']; + + $attributes = $element['#attributes']; + $attributes['id'] = $element['#id']; + $attributes['class'][] = 'chart'; + + return '<div ' . drupal_attributes($attributes) . '>' . (isset($element['#chart']) ? $element['#chart'] : '') . '</div>'; +} diff --git a/modules/charts_google/charts_google.inc b/modules/charts_google/charts_google.inc index 559dcb2..22d6a15 100644 --- a/modules/charts_google/charts_google.inc +++ b/modules/charts_google/charts_google.inc @@ -30,9 +30,9 @@ function _charts_google_render($chart) { // Trim out empty options. charts_trim_array($chart_definition['options']); - $chart['#theme'] = 'charts_google_chart'; $chart['#attached']['library'][] = array('charts_google', 'charts_google'); - $chart['#attached']['js'][] = array('data' => array('chartsGoogle' => array($chart['#id'] => $chart_definition)), 'type' => 'setting'); + $chart['#attributes']['class'][] = 'charts-google'; + $chart['#attributes']['data-chart'] = drupal_json_encode($chart_definition); return $chart; } @@ -105,7 +105,7 @@ function _charts_google_populate_chart_axes($chart, $chart_definition) { // Populate the chart data. $axis = array(); - $axis['title'] = $chart[$key]['#title']; + $axis['title'] = $chart[$key]['#title'] ? $chart[$key]['#title'] : ''; $axis['titleTextStyle']['color'] = $chart[$key]['#title_color']; $axis['titleTextStyle']['bold'] = $chart[$key]['#title_font_weight'] === 'bold' ? TRUE : FALSE; $axis['titleTextStyle']['italic'] = $chart[$key]['#title_font_style'] === 'italic' ? TRUE : FALSE; @@ -126,8 +126,8 @@ function _charts_google_populate_chart_axes($chart, $chart_definition) { $axis['baselineColor'] = $chart[$key]['#base_line_color']; $axis['minorGridlines']['color'] = $chart[$key]['#minor_grid_line_color']; $axis['viewWindowMode'] = isset($chart[$key]['#max']) ? 'explicit' : NULL; - $axis['viewWindow']['max'] = isset($chart[$key]['#max']) ? $chart[$key]['#max'] : NULL; - $axis['viewWindow']['min'] = isset($chart[$key]['#max']) ? (int) $chart[$key]['#min'] : NULL; + $axis['viewWindow']['max'] = strlen($chart[$key]['#max']) ? (int) $chart[$key]['#max'] : NULL; + $axis['viewWindow']['min'] = strlen($chart[$key]['#min']) ? (int) $chart[$key]['#min'] : NULL; // Multi-axis support only applies to the major axis in Google charts. $chart_type_info = chart_get_type($chart['#chart_type']); @@ -292,16 +292,3 @@ function _charts_google_populate_chart_data(&$chart, $chart_definition) { return $chart_definition; } - -/** - * Output the chart renderable as a string. - */ -function theme_charts_google_chart($variables) { - $element = $variables['element']; - - $attributes = $element['#attributes']; - $attributes['id'] = $element['#id']; - $attributes['class'][] = 'chart-render'; - - return '<div ' . drupal_attributes($attributes) . '></div>'; -} diff --git a/modules/charts_google/charts_google.js b/modules/charts_google/charts_google.js index 50f2a7d..feeba5e 100644 --- a/modules/charts_google/charts_google.js +++ b/modules/charts_google/charts_google.js @@ -6,16 +6,20 @@ Drupal.behaviors.chartsGoogle = {}; Drupal.behaviors.chartsGoogle.attach = function(context, settings) { - google.setOnLoadCallback(renderCharts); + // First time loading in Views preview may not work because the Google JS + // API may not yet be loaded. + if (typeof google !== 'undefined') { + google.load('visualization', '1', { callback: renderCharts }); + } + function renderCharts() { - for (var elementId in settings['chartsGoogle']) { - if (settings['chartsGoogle'].hasOwnProperty(elementId)) { - var config = settings['chartsGoogle'][elementId]; + $('.charts-google').once('charts-google-processed', function() { + if ($(this).attr('data-chart')) { + var config = $.parseJSON($(this).attr('data-chart')); var wrap = new google.visualization.ChartWrapper(); wrap.setChartType(config.visualization); wrap.setDataTable(config.data); wrap.setOptions(config.options); - wrap.setContainerId(elementId); // Apply data formatters. This only affects tooltips. The same format is // already applied via the hAxis/vAxis.format option. @@ -79,9 +83,9 @@ Drupal.behaviors.chartsGoogle.attach = function(context, settings) { } } - wrap.draw(); + wrap.draw(this); } - } + }); } }; diff --git a/modules/charts_google/charts_google.module b/modules/charts_google/charts_google.module index f2d8472..1bfd99d 100644 --- a/modules/charts_google/charts_google.module +++ b/modules/charts_google/charts_google.module @@ -13,17 +13,6 @@ function charts_google_charts_info() { return $info; } -/** - * Implements hook_theme(). - */ -function charts_google_theme() { - $info['charts_google_chart'] = array( - 'render element' => 'element', - 'file' => 'charts_google.inc', - ); - return $info; -} - /** * Implements hook_library(). */ @@ -33,7 +22,7 @@ function charts_google_library() { 'website' => 'https://google-developers.appspot.com/chart/', 'version' => '1.0', 'js' => array( - array('data' => 'https://www.google.com/jsapi?autoload=' . urlencode('{"modules":[{"name":"visualization","version":"1","packages":["corechart","table"]}]}'), 'type' => 'external'), + array('data' => 'https://www.google.com/jsapi', 'type' => 'external'), ), ); $library['charts_google'] = array( diff --git a/modules/charts_highcharts/charts_highcharts.inc b/modules/charts_highcharts/charts_highcharts.inc index 5b0b8d9..4caaa8b 100644 --- a/modules/charts_highcharts/charts_highcharts.inc +++ b/modules/charts_highcharts/charts_highcharts.inc @@ -38,9 +38,9 @@ function _charts_highcharts_render($chart) { $chart['#id'] = drupal_html_id('highchart-render'); } - $chart['#theme'] = 'charts_highcharts_chart'; $chart['#attached']['library'][] = array('charts_highcharts', 'charts_highcharts'); - $chart['#attached']['js'][] = array('data' => array('chartsHighcharts' => array($chart['#id'] => $chart_definition)), 'type' => 'setting'); + $chart['#attributes']['class'][] = 'charts-highchart'; + $chart['#attributes']['data-chart'] = drupal_json_encode($chart_definition); return $chart; } @@ -66,7 +66,7 @@ function _charts_highcharts_type($renderable_type) { */ function _charts_highcharts_populate_chart_options($chart, $chart_definition) { $chart_definition['chart']['type'] = $chart['#chart_type']; - $chart_definition['title']['text'] = $chart['#title']; + $chart_definition['title']['text'] = $chart['#title'] ? $chart['#title'] : ''; $chart_definition['title']['style']['color'] = $chart['#title_color']; $chart_definition['title']['style']['fontWeight'] = $chart['#title_font_weight']; $chart_definition['title']['style']['fontStyle'] = $chart['#title_font_style']; @@ -295,16 +295,3 @@ function _charts_highcharts_populate_chart_data(&$chart, $chart_definition) { return $chart_definition; } - -/** - * Output the chart renderable as a string. - */ -function theme_charts_highcharts_chart($variables) { - $element = $variables['element']; - - $attributes = $element['#attributes']; - $attributes['id'] = $element['#id']; - $attributes['class'][] = 'chart-render'; - - return '<div ' . drupal_attributes($attributes) . '></div>'; -} diff --git a/modules/charts_highcharts/charts_highcharts.js b/modules/charts_highcharts/charts_highcharts.js index 5418eea..5519c01 100644 --- a/modules/charts_highcharts/charts_highcharts.js +++ b/modules/charts_highcharts/charts_highcharts.js @@ -6,12 +6,12 @@ Drupal.behaviors.chartsHighcharts = {}; Drupal.behaviors.chartsHighcharts.attach = function(context, settings) { - for (var elementId in settings['chartsHighcharts']) { - if (settings['chartsHighcharts'].hasOwnProperty(elementId)) { - var config = settings['chartsHighcharts'][elementId]; - $('#' + elementId).highcharts(config); + $('.charts-highchart').once('charts-highchart-processed', function() { + if ($(this).attr('data-chart')) { + var config = $.parseJSON($(this).attr('data-chart')); + $(this).highcharts(config); } - } + }); }; })(jQuery); diff --git a/modules/charts_highcharts/charts_highcharts.module b/modules/charts_highcharts/charts_highcharts.module index 92af1c6..bd761ec 100644 --- a/modules/charts_highcharts/charts_highcharts.module +++ b/modules/charts_highcharts/charts_highcharts.module @@ -17,17 +17,6 @@ function charts_highcharts_charts_info() { return $info; } -/** - * Implements hook_theme(). - */ -function charts_highcharts_theme() { - $info['charts_highcharts_chart'] = array( - 'render element' => 'element', - 'file' => 'charts_highcharts.inc', - ); - return $info; -} - /** * Implements hook_library(). */ diff --git a/views/charts_plugin_style_chart.inc b/views/charts_plugin_style_chart.inc index aa7cba8..1dae418 100644 --- a/views/charts_plugin_style_chart.inc +++ b/views/charts_plugin_style_chart.inc @@ -58,13 +58,35 @@ class charts_plugin_style_chart extends views_plugin_style { } /** - * Define and display a chart from the grouped values. + * Make sure the display and all associated handlers are valid. + * + * @return + * Empty array if the display is valid; an array of error strings if it is not. */ - function render() { - if (!empty($this->view->preview)) { - return t('Preview is not supported with the chart display type.'); + function validate() { + $errors = array(); + $field_handlers = $this->display->handler->get_handlers('field'); + + if (count($field_handlers)) { + $data_field_key = !empty($this->options['data_fields']) ? current($this->options['data_fields']) : NULL; + if (empty($data_field_key)) { + $errors[] = t('At least one data field must be selected in the chart configuration before this chart may be shown'); + } + else { + $data_field = isset($field_handlers[$data_field_key]) ? $field_handlers[$data_field_key] : NULL; + if (!isset($data_field)) { + $errors[] = t('A field you have specified as a data field in your chart settings no longer exists. Edit the chart settings and select at least one data field.'); + } + } } + return $errors; + } + + /** + * Define and display a chart from the grouped values. + */ + function render() { // Calculate the labels field alias. $field_handlers = $this->display->handler->get_handlers('field'); $label_field = FALSE; @@ -91,10 +113,6 @@ class charts_plugin_style_chart extends views_plugin_style { $data_field_key = current($this->options['data_fields']); $data_field = isset($field_handlers[$data_field_key]) ? $field_handlers[$data_field_key] : NULL; - if (!isset($data_field)) { - return t('At least one field must be set as a data source in the chart format configuration.'); - } - $data = array(); foreach ($this->view->result as $row) { $data_row = array(); -- GitLab