diff --git a/graphael-views-view-chart.tpl.php b/graphael-views-view-chart.tpl.php new file mode 100644 index 0000000..c3addb0 --- /dev/null +++ b/graphael-views-view-chart.tpl.php @@ -0,0 +1 @@ + diff --git a/graphael.module b/graphael.module index b658a08..99b7be9 100644 --- a/graphael.module +++ b/graphael.module @@ -75,6 +75,38 @@ function graphael_theme() { 'attr' => array(), ), ), + 'graphael_views_ui_style_plugin_chart' => array( + 'arguments' => array('form' => NULL), + ), + ); +} + +// views hooks: http://groups.drupal.org/node/10129 + +/** + * Implementatin of hook_views_api() + */ +function graphael_views_api() { + return array('api' => '3.0-alpha1'); +} + +/** + * Implementation of hook_views_plugins(). + */ +function graphael_views_plugins() { + return array( + 'style' => array( + 'graphael_views' => array( + 'title' => t('gRaphaƫl chart'), + 'theme' => 'graphael_views_view_chart', + 'help' => t('Display nodes as a chart'), + 'handler' => 'graphael_plugin_style_chart', + 'uses fields' => TRUE, + 'uses options' => TRUE, + 'uses row plugin' => TRUE, + 'type' => 'normal', + ), + ), ); } @@ -107,3 +139,40 @@ function template_preprocess_graphael(&$vars) { $vars['attr']['style'] = isset($vars['attr']['style']) ? $vars['attr']['style'] : 'height:200px; width:400px;'; } +/* + * Preprocess the primary theme implementation for a view. + */ +function template_preprocess_graphael_views_view_chart(&$vars) { + $view = $vars['view']; + $handler = $view->style_plugin; + $vars['chart'] = $handler->render_raw(); +} + +/** + * Theme function for views plugin form. + */ +function theme_graphael_views_ui_style_plugin_chart($form) { + $output = ''; + + $header = array( + t('Data(x)'), + t('Data(y)'), + t('Label'), + t('url'), + ); + + $rows = array(); + foreach (element_children($form['series']) as $id) { + $row = array(); + $row[] = drupal_render($form['series'][$id]['x']); + $row[] = drupal_render($form['series'][$id]['y']); + $row[] = drupal_render($form['series'][$id]['label']); + $row[] = drupal_render($form['series'][$id]['url']); + $rows[] = $row; + } + $output .= drupal_render($form); + + $output .= theme('table', $header, $rows); + + return $output; +} \ No newline at end of file diff --git a/graphael_plugin_style_chart.inc b/graphael_plugin_style_chart.inc new file mode 100644 index 0000000..dc7cde2 --- /dev/null +++ b/graphael_plugin_style_chart.inc @@ -0,0 +1,192 @@ + 'select', + '#title' => t('Chart type'), + '#options' => array('pie' => t('Pie'), 'bar' => t('Bar'), 'line' => t('Line')), + '#default_value' => $this->options['chart_type'], + ); + + // Create an array of allowed columns from the data we know: + $field_names = $this->display->handler->get_field_labels(); + array_unshift($field_names, t('None')); + + // conditional field only show if chart_type = 'line' + $form['autox'] = array( + '#type' => 'checkbox', + '#title' => t('Auto X'), + '#description' => t('If checked use auto-increment integer values for x data. Otherwise X values will be explicitly selected'), + '#default_value' => !empty($this->options['autox']) ? $this->options['autox'] : FALSE, + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => array('line')), + ); + + // conditional field, only show if chart_type = 'bar' + $form['bar_type'] = array( + '#type' => 'select', + '#title' => t('Bar style'), + '#description' => t('Available styles for the tip of the bars.'), + '#options' => array('square' => t('Square'), 'soft' => t('Soft'), 'round' => t('Round'), 'sharp' => t('Sharp')), + '#default_value' => $this->options['bar_type'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => array('bar')), + // '' => '', + ); + + $form['#theme'] = 'graphael_views_ui_style_plugin_chart'; + + // Series should be number of fields. + $num_fields = count($this->display->display_options['fields']); + $count = $num_fields > 0 ? $num_fields : 1; + + for ($i=1; $i <= $count; $i++) { + if ($i == 1) { + $dependency = array('bar', 'line', 'pie'); + $url_dependency = array('bar', 'pie'); + } + else { + $dependency = array('bar'); + $url_dependency = array('bar'); + } + + $form['series'][$i]['x'] = array( + '#type' => 'select', + '#default_value' => $this->options['series'][$i]['x'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => $dependency), + '#options' => $field_names, + ); + + $form['series'][$i]['y'] = array( + '#type' => 'select', + '#default_value' => $this->options['series'][$i]['y'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => $dependency), + '#options' => $field_names, + ); + + $form['series'][$i]['label'] = array( + '#type' => 'select', + '#default_value' => $this->options['series'][$i]['label'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => $dependency), + '#options' => $field_names, + ); + + $form['series'][$i]['url'] = array( + '#type' => 'select', + '#default_value' => $this->options['series'][$i]['url'], + '#process' => array('views_process_dependency'), + '#dependency' => array('edit-style-options-chart-type' => $url_dependency), + '#options' => $field_names, + ); + } + } + + function render_raw() { + if (isset($this->rendered_raw)) { + return $this->rendered_raw; + } + + $data = array(); + // Get the raw date into data array. + foreach($this->options['series'] as $i => $series) { + // Must have a y value to use + if (!empty($series['y'])) { + foreach (array_filter($series) as $type => $field) { + // Raw values are used for x and y values + if (in_array($type, array('x', 'y'))) { + // Get the field alias name, that views uses as key. + $row_name = $this->view->field[$field]->field_alias; + $raw_data_result = array(); + // Get the data from the raw data. + foreach ($this->view->result as $raw_data) { + $raw_data_result[] = (int) $raw_data->$row_name; + } + $data[$i][$type] = $raw_data_result; + } + else { + $raw_data_result = array(); + foreach ($this->rendered_fields as $rendered) { + $raw_data_result[] = $rendered[$field]; + } + $data[$i][$type] = $raw_data_result; + } + } + } + } + + $params = array(); + $extend = array(); + $final = array(); + foreach($this->options['series'] as $i => $series) { + + // all chart types have to have the 'y' values set to be considered "live" + if (!empty($series['y'])) { + + switch ($this->options['chart_type']) { + case 'pie': + $final = $data[$i]['y']; + break; + case 'bar': + if (isset($data[$i]['x']) && count($data) == 0) { + $final[] = array($data[$i]['x'], $data[$i]['y']); + } + else { + $final[] = $data[$i]['y']; + } + $params['opts']['type'] = $this->options['bar_type']; + break; + case 'line': + $final = array($data[$i]['x'], $data[$i]['y']); + } + + if ($series['label'] != '0') { + $extend['label']['values'] = $data[$i]['label']; + } + + if ($series['url'] != '0') { + $extend['url']['values'] = $data[$series['url']]; + } + } + } + + if ($this->options['legend'] != '0') { + $raw_data_result = array(); + foreach ($this->rendered_fields as $rendered) { + // Maybe it should be an option if procent should be added and number of decimals + $raw_data_result[] = '%%.% - ' . $rendered[$this->options['legend']]; + } + $params['opts']['legend'] = $raw_data_result; + } + + // if we only have one data series pop it off to a non-array... again this will likely be affected by + // jquery binding support for multiple series. + if (count($final) == 1) { + $final = array_pop($final); + } + + // @TODO: remove this notes + // Notes to remember some config options available (for bar graphs only) but not so easy to figure (graphael isn't documented as of now) +/* $params['padding'] = 15; //internal padding of the graph + $extend['label']['params']['label'] = 'label'; // type of the label, available options are: tag, popup, flag, label, drop and blob + $extend['label']['params']['attrLabel'] = array('fill' => '#000000'); //fillcolor for the label + $extend['label']['params']['attrText'] = array('fill' => '#dddddd'); // color for the text of the label */ + + return theme('graphael', $this->options['chart_type'], $final, $params, $extend); + } +}