diff --git a/charts.module b/charts.module index cfe52ece334a1f546b707e10811c30ccede884ca..846363ba5c49055914aa3f03175b934913e339fe 100644 --- a/charts.module +++ b/charts.module @@ -28,6 +28,7 @@ function charts_theme($existing, $type, $theme, $path) { function template_preprocess_views_view_charts(&$variables) { $options = $variables['view']->style_plugin->options; + $attachmentDisplayOptions = []; $service = \Drupal::service('charts.charts_attachment'); $attachmentView = $service->getAttachmentViews(); @@ -38,18 +39,21 @@ function template_preprocess_views_view_charts(&$variables) { $chartId = $viewId . '__' . $displayId; $categoriesAttachment = array(); $seriesDataAttachment = array(); + $attachmentChartTypeOption = array(); for ($i = 0; $i < count($attachmentView); $i++) { $attachmentId = $attachmentView[$i]->display_handler->display['id']; $attachmentDisplay = $view->storage->getDisplay($attachmentId); + $attachmentChartType = $attachmentDisplay['display_options']['style']['options']['type']; + array_push($attachmentChartTypeOption, $attachmentChartType); $attachedValueField = $attachmentDisplay['display_options']['style']['options']['data_fields']; $combinedAttachmentPage = Util::removeUnselectedFields($attachedValueField); $attachmentColor = $attachmentView[$i]->style_plugin->options['field_colors']; $labelField = $attachmentView[$i]->style_plugin->options['label_field']; - $dataAttachment = Util::viewsData($attachmentView[$i], $combinedAttachmentPage, $labelField, $attachmentColor); + $dataAttachment = Util::viewsData($attachmentView[$i], $combinedAttachmentPage, $labelField, $attachmentColor, $attachmentChartTypeOption[$i]); $dataAttachmentFormatted = Util::createChartableData($dataAttachment); for ($j = 0; $j < count($dataAttachmentFormatted[0]); $j++) { @@ -60,25 +64,38 @@ function template_preprocess_views_view_charts(&$variables) { array_push($seriesDataAttachment, $dataAttachmentFormatted[1][$j]); } } - $library = $view->style_plugin->options['library']; $variables['data'] = array(); $labelField = $view->style_plugin->options['label_field']; $valueField = $view->style_plugin->options['data_fields']; $valueField = Util::removeUnselectedFields($valueField); $color = $view->style_plugin->options['field_colors']; - $data = Util::viewsData($view, $valueField, $labelField, $color); + + if (0 < count($attachmentView)){ + $data = Util::viewsData($view, $valueField, $labelField, $color, $attachmentChartTypeOption[$i]); + } else { + $data = Util::viewsData($view, $valueField, $labelField, $color, $attachmentChartTypeOption[$i] = NULL); + } + $data = Util::createChartableData($data); $categories = $data[0]; $seriesData = $data[1]; $categories = array_merge($categories, $categoriesAttachment); + $categories = array_unique($categories); + + for ($i =0; $i < count($attachmentView); $i++){ + $attachmentId = $attachmentView[$i]->display_handler->display['id']; + $attachmentDisplay = $view->storage->getDisplay($attachmentId); + $attachmentDisplayOptions[$i] = $attachmentDisplay['display_options']; + } $seriesData = array_merge($seriesData, $seriesDataAttachment); // Handles the toggling from one library to another. switch ($library) { case 'google': + Util::checkMissingLibrary('charts_google', '/vendor/google/loader.js'); $googleData = charts_google_render_charts($categories, $seriesData); - $googleOptions = charts_google_create_charts_options($options, $seriesData); + $googleOptions = charts_google_create_charts_options($options, $seriesData, $attachmentDisplayOptions); $googleChartType = charts_google_create_chart_type($options); $variables['chart_type'] = 'google'; $variables['attributes']['class'][0] = 'charts-google'; @@ -90,7 +107,8 @@ function template_preprocess_views_view_charts(&$variables) { break; case 'highcharts': - $highchart = charts_highcharts_render_charts($options, $categories, $seriesData); + Util::checkMissingLibrary('charts_highcharts', '/vendor/highcharts/highcharts.js'); + $highchart = charts_highcharts_render_charts($options, $categories, $seriesData, $attachmentDisplayOptions); $variables['chart_type'] = 'highcharts'; $variables['content_attributes']['data-chart'][] = json_encode($highchart); $variables['attributes']['id'][0] = $chartId; @@ -99,7 +117,8 @@ function template_preprocess_views_view_charts(&$variables) { break; case 'c3': - $c3 = charts_c3_render_charts($options, $categories, $seriesData, $chartId); + Util::checkMissingLibrary('charts_c3', '/vendor/cthree/c3.min.js'); + $c3 = charts_c3_render_charts($options, $categories, $seriesData, $chartId, $attachmentDisplayOptions); $variables['chart_type'] = 'c3'; $variables['content_attributes']['data-chart'][] = json_encode($c3); $variables['attributes']['id'][0] = $chartId; @@ -111,3 +130,5 @@ function template_preprocess_views_view_charts(&$variables) { } } + + diff --git a/modules/charts_c3/charts_c3.module b/modules/charts_c3/charts_c3.module index 7efc0205953351b5ee09b2ec9f702ea58bb8b5da..0f7023577fb0d773b0bd94b5db6a8f7217eb334f 100644 --- a/modules/charts_c3/charts_c3.module +++ b/modules/charts_c3/charts_c3.module @@ -23,8 +23,31 @@ function charts_c3_charts_info() { return $info; } -function charts_c3_render_charts($options, $categories = array(), $seriesData = array(), $chartId) { +/** + * @param $options + * @param array $categories + * @param array $seriesData + * @param $chartId + * @param array $attachmentDisplayOptions + * + * @return CThree + */ +function charts_c3_render_charts($options, $categories = array(), $seriesData = array(), $chartId, $attachmentDisplayOptions = []) { + $noAttachmentDisplays = count($attachmentDisplayOptions); + $yAxis = []; + $types = []; + //sets secondary axis from the first attachment only + if ($attachmentDisplayOptions[0]['inherit_yaxis'] == 0){ + $yAxis[$seriesData[1]['name']] = 'y2'; + } + + for ($i = 1; $i <= count($attachmentDisplayOptions); $i++){ + if ($attachmentDisplayOptions[$i - 1]['style']['options']['type'] == 'column') + $types[$seriesData[$i]['name']] = 'bar'; + else + $types[$seriesData[$i]['name']] = $attachmentDisplayOptions[$i - 1]['style']['options']['type']; + } $c3Data = array(); for ($i = 0; $i < count($seriesData); $i++) { $c3DataTemp = $seriesData[$i]['data']; @@ -44,7 +67,15 @@ function charts_c3_render_charts($options, $categories = array(), $seriesData = //$c3->setLabels($options['data_labels']); $c3->setTitle($c3ChartTitle); $chartData = new ChartData(); - + if ($noAttachmentDisplays > 0){ + $chartData->setLabels(FALSE); + } + if ($attachmentDisplayOptions[0]['inherit_yaxis'] == 0){ + $chartData->axes = $yAxis; + $showSecAxis['show'] = true; + $showSecAxis['label'] = $attachmentDisplayOptions[0]['style']['options']['yaxis_title']; + $chartAxis->y2 = $showSecAxis; + } $chartData->setType($options['type']); $c3->setData($chartData); if ($options['type'] == 'bar') { @@ -67,6 +98,7 @@ function charts_c3_render_charts($options, $categories = array(), $seriesData = $chartData->setColumns($c3Data); } } + $chartData->types = $types; $c3->setAxis($chartAxis); @@ -79,6 +111,5 @@ function charts_c3_render_charts($options, $categories = array(), $seriesData = $chartColor->setPattern($seriesColors); $c3->setColor($chartColor); - return $c3; } diff --git a/modules/charts_google/charts_google.module b/modules/charts_google/charts_google.module index 45aed4b1e6f30d8488863a904dc05c9fbc51937e..ba5c3514923aaa91edf5edea665ce89c485123a1 100644 --- a/modules/charts_google/charts_google.module +++ b/modules/charts_google/charts_google.module @@ -32,12 +32,6 @@ function charts_google_charts_info() { function charts_google_render_charts($categories = array(), $seriesData = array()) { $dataTable = array(); - - $dataTableHeader = array(); - for ($r = 0; $r < count($seriesData); $r++) { - array_push($dataTableHeader, $seriesData[$r]['name']); - } - for ($j = 0; $j < count($categories); $j++) { $rowDataTable = []; for ($i = 0; $i < count($seriesData); $i++) { @@ -62,12 +56,47 @@ function charts_google_render_charts($categories = array(), $seriesData = array( /** * @param $options * @param array $seriesData + * @param array $attachmentDisplayOptions * @return GoogleOptions object with chart options or settings to be used by google visualization framework */ -function charts_google_create_charts_options($options, $seriesData = array()) { +function charts_google_create_charts_options($options, $seriesData = array(), $attachmentDisplayOptions = []) { + $chartSelected = []; + $seriesTypes = array(); + $firstVaxis = array('minValue'=> 0, 'title' => $options['yaxis_title']); + $secondVaxis = array('minValue'=> 0); + $vAxes = array(); + array_push($vAxes, $firstVaxis); + //sets secondary axis from the first attachment only + if ($attachmentDisplayOptions[0]['inherit_yaxis'] == 0){ + $secondVaxis['title'] = $attachmentDisplayOptions[0]['style']['options']['yaxis_title']; + array_push($vAxes, $secondVaxis); + } + array_push($chartSelected, $options['type']); + for ($i = 0; $i < count($attachmentDisplayOptions); $i++){ + $attachmentChartType = $attachmentDisplayOptions[$i]['style']['options']['type']; + if ($attachmentChartType == 'column') + $attachmentChartType = 'bars'; + if ($attachmentDisplayOptions[0]['inherit_yaxis'] == 0 && $i == 0){ + $seriesTypes[$i + 1] = array('type' => $attachmentChartType, 'targetAxisIndex' => 1); + } + else + $seriesTypes[$i + 1] = array('type' => $attachmentChartType); + array_push($chartSelected, $attachmentChartType); + } + $chartSelected = array_unique($chartSelected); $googleOptions = new GoogleOptions(); + if (count($chartSelected) > 1){ + $parentChartType = $options['type']; + if ($parentChartType == 'column') + $parentChartType = 'bars'; + $googleOptions->seriesType = $parentChartType; + $googleOptions->series = $seriesTypes; + } $googleOptions->setTitle($options['title']); + $googleOptions->vAxes = $vAxes; + //$vAxis['title'] = $options['yaxis_title']; + //$googleOptions->setVAxis($vAxis); $chartArea = new ChartArea(); $chartArea->setWidth(400); // $googleOptions->setChartArea($chartArea); diff --git a/modules/charts_google/src/Settings/Google/VerticalAxis.php b/modules/charts_google/src/Settings/Google/VerticalAxis.php index d9a99ed363ae19666bfb20b10a19d429c5a5dbeb..017d73f6dcc947188f479a5c84126715424fdc63 100644 --- a/modules/charts_google/src/Settings/Google/VerticalAxis.php +++ b/modules/charts_google/src/Settings/Google/VerticalAxis.php @@ -4,4 +4,5 @@ namespace Drupal\charts_google\Settings\Google; class VerticalAxis { private $title; + } diff --git a/modules/charts_highcharts/charts_highcharts.module b/modules/charts_highcharts/charts_highcharts.module index da2bf37e23ab41827ad205d75fc484ee2eb673db..14cb767f38a563086c5574bb75c0d4cd6a5db401 100644 --- a/modules/charts_highcharts/charts_highcharts.module +++ b/modules/charts_highcharts/charts_highcharts.module @@ -39,9 +39,12 @@ function charts_highcharts_charts_info() { * @param array $categories * @param array $seriesData * + * @param array $attachmentDisplayOptions + * * @return Highcharts object to be used by highcharts javascripts visualization framework */ -function charts_highcharts_render_charts($options, $categories = array(), $seriesData = array()) { +function charts_highcharts_render_charts($options, $categories = array(), $seriesData = array(), $attachmentDisplayOptions = []) { + $chart = new ChartType(); $chart->setType($options['type']); $chartTitle = new ChartTitle(); @@ -55,6 +58,7 @@ function charts_highcharts_render_charts($options, $categories = array(), $serie $chartXaxis->setLabels($chartLabels); $yaxisLabels = new YaxisLabel(); $chartYaxis = new Yaxis(); + $yAxes = []; $yAxisTitle = new YaxisTitle(); $yAxisTitle->setText($options['yaxis_title']); if (!empty($options['yaxis_min'])){ @@ -63,8 +67,27 @@ function charts_highcharts_render_charts($options, $categories = array(), $serie if (!empty($options['yaxis_max'])){ $chartYaxis->max = $options['yaxis_max']; } + $chartYaxis->setLabels($yaxisLabels); $chartYaxis->setTitle($yAxisTitle); + array_push($yAxes, $chartYaxis); + // Chart libraries tend to supports only one secondary axis. + if ($attachmentDisplayOptions[0]['inherit_yaxis'] == 0){ + $chartYaxisSecondary = new Yaxis(); + $yAxisTitleSecondary = new YaxisTitle(); + $yAxisTitleSecondary->setText($attachmentDisplayOptions[0]['style']['options']['yaxis_title']); + $chartYaxisSecondary->setTitle($yAxisTitleSecondary); + $chartYaxisSecondary->setLabels($yaxisLabels); + $chartYaxisSecondary->opposite = 'true'; + + if (!empty($attachmentDisplayOptions[0]['style']['options']['yaxis_min'])){ + $chartYaxisSecondary->min = $attachmentDisplayOptions[0]['style']['options']['yaxis_min']; + } + if (!empty($attachmentDisplayOptions[0]['style']['options']['yaxis_max'])){ + $chartYaxisSecondary->max = $attachmentDisplayOptions[0]['style']['options']['yaxis_max']; + } + array_push($yAxes, $chartYaxisSecondary); + } $dataLabelStatus = new DataLabelStatus(); $dataLabels = new DataLabels(); $dataLabels->setDataLabels($dataLabelStatus); @@ -78,7 +101,8 @@ function charts_highcharts_render_charts($options, $categories = array(), $serie $highchart->setChart($chart); $highchart->setTitle($chartTitle); $highchart->setXAxis($chartXaxis); - $highchart->setYAxis($chartYaxis); + //$highchart->setYAxis($chartYaxis); + $highchart->yAxis = $yAxes; $highchart->setTooltip($chartTooltip); $highchart->setPlotOptions($barPlotOptns); $highchart->setCredits($chartCredits); diff --git a/modules/charts_highcharts/src/Settings/Highcharts/Highcharts.php b/modules/charts_highcharts/src/Settings/Highcharts/Highcharts.php index 880a88ee14185cbe9673e57af3d9725568b7c6f1..cb556d5db8f812aebb02ca19c755874e4ea0ed18 100644 --- a/modules/charts_highcharts/src/Settings/Highcharts/Highcharts.php +++ b/modules/charts_highcharts/src/Settings/Highcharts/Highcharts.php @@ -6,7 +6,7 @@ class Highcharts implements \JsonSerializable { private $chart; private $title; private $xAxis; - private $yAxis; + // private $yAxis; private $tooltip; private $plotOptions; private $legend; @@ -57,16 +57,16 @@ class Highcharts implements \JsonSerializable { /** * @return mixed */ - public function getYAxis() { + /*public function getYAxis() { return $this->yAxis; - } + }*/ /** * @param mixed $yAxis */ - public function setYAxis($yAxis) { + /* public function setYAxis($yAxis) { $this->yAxis = $yAxis; - } + }*/ /** * @return mixed diff --git a/src/Util/Util.php b/src/Util/Util.php index f190d0bad4c41417bbf1d075e26f30e3dc35faea..4bb54f8bb3d8ed8c6088fceff08c6b405d1058e1 100644 --- a/src/Util/Util.php +++ b/src/Util/Util.php @@ -11,7 +11,7 @@ class Util { * @param $color * @return array */ - public static function viewsData($view, $labelValues, $labelField, $color) { + public static function viewsData($view, $labelValues, $labelField, $color, $attachmentChartTypeOption) { $data = array(); foreach ($view->result as $id => $row) { @@ -24,6 +24,7 @@ class Util { 'label' => $view->field[$fieldId]->label(), // 'label' => $view->display_handler->display['id'], to use display_id 'color' => $color[$fieldId], + 'type' => $attachmentChartTypeOption, ); $numberFields++; } @@ -58,11 +59,12 @@ class Util { for ($i = 0; $i < count($data[0]); $i++) { - $seriesRowData = array('name' => '', 'color' => '', 'data' => array()); + $seriesRowData = array('name' => '', 'color' => '', 'type' => '', 'data' => array()); for ($j = 0; $j < count($data); $j++) { $categories[$j] = $data[$j][$i]['label_field']; $seriesRowData['name'] = $data[$j][$i]['label']; // $seriesRowData['name'] = $data[$j][$i]['label_field']; + $seriesRowData['type'] = $data[$j][$i]['type']; $seriesRowData['color'] = $data[$j][$i]['color']; array_push($seriesRowData['data'], ((int) ($data[$j][$i]['value']))); } @@ -74,4 +76,19 @@ class Util { return $chartData; } + /** + * Checks for missing libraries necessary for data visualization + * + * @param $moduleName + * @param $libraryPath + * + */ + public static function checkMissingLibrary($moduleName, $libraryPath){ + $module_path = drupal_get_path('module', $moduleName); + if (!file_exists($module_path . $libraryPath)){ + drupal_set_message(t('Charting libraries for '.$moduleName.' might + not be installed. Run \'composer install\' for '.$moduleName.' sub-module.'), 'error'); + } + } + }