protected function create(Import\ImportStream $stream, Import\ImportContext $context) { $reports = $stream->get('reports'); if (empty($reports)) { return; } $this->datasourceName = $context->get('datasourceName'); $readOnly = gd_datasource_is_property($this->datasourceName, 'readonly'); if ($readOnly) { $metamodel = data_controller_get_metamodel(); $this->datasets = $metamodel->datasets; } else { $this->datasets = $stream->get('datasets'); } if (empty($this->datasets)) { throw new Exception('Must have datasets to create reports.'); } foreach ( $reports as $reportKey => $report ) { $node = $this->createReport($report); if ( !empty($node->nid ) ) { $reports[$reportKey] = $node; } else { throw new Exception('Report node creation failed'); } } $stream->set('reports',$reports); }
public function getView( array $options = array() ) { $scrollHeight = 400; $heightAdj = 0; if ( $this->ReportConfig->showTitle() || $this->ReportConfig->showMenu() ) { $heightAdj = (GD_REPORT_TITLE_HEIGHT); } $reportSize = $this->ReportConfig->getDisplaySize(); if ( !empty($reportSize) ) { $scrollHeight = $reportSize->height; } if ( isset($_REQUEST['h']) && isset($_REQUEST['w']) ) { $scrollHeight = $_REQUEST['h']; } $scrollHeight -= $heightAdj; $width = isset($_REQUEST['w']) ? $_REQUEST['w'] . 'px' : '100%'; $datasourceName = $this->ReportConfig->getNode() != null ? get_node_field_value($this->ReportConfig->getNode(), 'field_report_datasource') : null; if (!isset($datasourceName)) { $datasourceName = gd_datasource_get_active(); } $viewStart = gd_datasource_is_property($datasourceName, 'draft') ? '<img id="report-'.intval($this->ReportConfig->getId()).'-overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/> <script type="text/javascript"> jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").bind("mouseenter mouseleave click dblclick foucsout hover mousedown mousemove mouseout mouseover mouseup", function (e) { if (navigator.appName == "Microsoft Internet Explorer") { jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").hide(); var target = document.elementFromPoint(e.clientX, e.clientY); jQuery(target).trigger(e.type); jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").show(); } }); </script>' : ''; $viewStart .= '<div class="report report-custom" id="report-'.intval($this->ReportConfig->getId()).'" style="width:' . $width . ';height:' . $scrollHeight . 'px;clear:both; overflow:hidden;position:relative;">'; $viewEnd = '</div>'; $viewBody = $this->getBody($options); return $viewStart. $viewBody. $viewEnd; }
protected function create(Import\ImportStream $stream, Import\ImportContext $context) { $dashboards = (array) $stream->get('dashboards'); if (empty($dashboards)) { return; } $this->datasourceName = $context->get('datasourceName'); $this->reports = (array) $stream->get('reports'); $readOnly = gd_datasource_is_property($this->datasourceName, 'readonly'); if ($readOnly) { $metamodel = data_controller_get_metamodel(); $this->datasets = $metamodel->datasets; } else { $this->datasets = (array) $stream->get('datasets'); } if ( !empty($reports) && empty($datasets) ) { throw new Exception('Missing datasets for dashboard reports.'); } foreach ( $dashboards as $dashboardKey => $dashboard ) { $node = $this->createDashboard($dashboard); if ( !empty($node->nid ) ) { $dashboards[$dashboardKey] = $node; } else { throw new Exception('Dashboard node creation failed'); } } // update report/dashboard ids in config, for linking foreach ( $dashboards as $dashboardKey => $dashboard ) { $config = json_decode($dashboard->field_dashboard_config[$dashboard->language][0]['value']); $this->processConfigDashboards($config); $dashboards[$dashboardKey]->field_dashboard_config[$dashboards[$dashboardKey]->language][0]['value'] = json_encode($config); gd_dashboard_save($dashboards[$dashboardKey]); } $stream->set('dashboards',$dashboards); }
public function export(Export\ExportStream $stream, Export\ExportContext $context) { $datasource = gd_datasource_get_active(); $readOnly = gd_datasource_is_property($datasource, 'readonly'); if ($readOnly) { return; } $metamodel = data_controller_get_metamodel(); // get datasets $datasets = array(); foreach ($metamodel->datasets as $dataset) { if (!isset($dataset->nid)) { continue; } $datasets[] = $dataset; } $stream->set('datasets',$datasets); }
<?php if ((gd_datasource_is_property(gd_datasource_get_active(), 'draft'))) { ?> var overlay = null; if (navigator.appVersion.indexOf("MSIE 9.") !== -1) { overlay = $('<svg class="report-draft-overlay" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"><image alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" xlink:href="/sites/all/modules/custom/report/includes/images/draft.png" x="0" y="0" height="<?php echo $height > $width ? ('100%') : ($width . 'px'); ?>" width="<?php echo $width > $height ? ('100%') : ($height . 'px'); ?>"/></svg>'); } else { overlay = $('<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png" style="<?php echo $height > $width ? ( 'height') : ('width'); ?>: 100%;">'); } $('#report-<?php echo $reportId; ?>').append(overlay); <?php } ?> var urlOptions = { url: "<?php echo $url; ?>" }; global.GD.PivotTableFactory.createTable(<?php echo $reportId; ?>, "#report-<?php echo $reportId;?>", { measures: <?php echo json_encode($measures); ?>, draft: <?php echo (gd_datasource_is_property(gd_datasource_get_active(), 'draft') ? "true" : "false"); ?>, rows: <?php echo isset($rows) ? json_encode($rows): '[]'; ?>, cols: <?php echo isset($cols) ? json_encode($cols): '[]'; ?>, columns: <?php echo json_encode($columns); ?>, url: urlOptions, allowDragDrop: <?php echo $disableDrag; ?>, callType: "<?php echo ( isset($admin) ? "POST" : "GET" ) ?>", getDataObject: function(columns, measure) { if (!columns) { columns = []; } if (measure) { columns.push(measure); } <?php if (isset($admin) && !isset($dashboard)) { echo 'var config = GovdashReportBuilder.getReport().getConfig();';
/** * @return array * @throws Exception * @throws IllegalArgumentException */ function gd_dashboard_index_variables () { $dashboards = array(); $active_datasource_name = gd_datasource_find_active(); $current_dashboard = gd_dashboard_get_current(); global $user; if ( gd_account_user_is_admin() ) { // can see all datasources $datasources = gd_datasource_get_all(); if ( $current_dashboard ) { gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource')); } else if ( !$active_datasource_name ) { if (isset($_GET['ds'])) { gd_datasource_set_active($_GET['ds']); } else { gd_datasource_set_active(key($datasources)); } } // don't pick up any dashboards if there are no published datamarts - causes logic bomb further down if ( !empty($datasources) ) { $dashboards = gd_dashboard_findall_by_datasource(LOAD_ENTITY); } } else if ( $user->uid ) { // get view privileges for all dashboards $results = gd_account_user_get_dashboards(); // pick up the datasources from the dashboards $datasources = gd_account_user_get_datasources(); foreach ( $results as $dashboard ) { if ( !isset($datasources[get_node_field_value($dashboard,'field_dashboard_datasource')]) ) { $datasource = gd_datasource_get(get_node_field_value($dashboard,'field_dashboard_datasource')); $datasources[$datasource->name] = $datasource; } } // set current datasource if ( $current_dashboard ) { gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource')); } else { if ( !$active_datasource_name ) { if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) { gd_datasource_set_active($_GET['ds']); } else { reset($results); try { if (!empty($results[key($results)])) { $active_datasource_name = get_node_field_value($results[key($results)],'field_dashboard_datasource'); gd_datasource_set_active($active_datasource_name); } else { return 'You have not been granted permission to view any dashboards.'; } } catch (Exception $e) { drupal_set_message('No default datasource set.', 'error'); LogHelper::log_error($e->getMessage()); } } } } // remove dashboards that do not belong to datasource of current dashboard $active_datasource_name = gd_datasource_get_active(); $dashboards = array(); foreach ( $results as $key => $dashboard ) { if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) { $dashboards[$key] = $dashboard; } } // remove dashboards that were not created by the user if ( gd_datasource_is_property($active_datasource_name, 'personal') ) { global $user; $userCreatedDashboards = array(); foreach ( $dashboards as $key => $dashboard ) { if ( $user->uid == $dashboard->uid ) { $userCreatedDashboards[$key] = $dashboard; } } $dashboards = $userCreatedDashboards; // overwrite dashboard list } } else { // get datasources that belong to the dashboards // weed out dashboards with missing datasource $datasources = array(); $publicDashboards = array(); foreach ( gd_dashboard_get_dashboards_public(LOAD_ENTITY) as $dashboard ) { $datasourceName = get_node_field_value($dashboard,'field_dashboard_datasource'); $datasource = gd_datasource_find($datasourceName); if ( !$datasource ) { continue; } $publicDashboards[$dashboard->nid] = $dashboard; if ( !isset($datasources[$datasourceName]) ) { $datasources[$datasource->name] = $datasource; } } // set current datamart if ( $current_dashboard ) { gd_datasource_set_active(get_node_field_value($current_dashboard,'field_dashboard_datasource')); } else { if ( isset($_GET['ds']) && isset($datasources[$_GET['ds']]) ) { gd_datasource_set_active($_GET['ds']); } else { gd_datasource_set_active(get_node_field_value($publicDashboards[key($publicDashboards)],'field_dashboard_datasource')); } } // remove dashboards that do not belong to datamart of current dashboard $active_datasource_name = gd_datasource_get_active(); $dashboards = array(); foreach ( $publicDashboards as $key => $dashboard ) { if ( $active_datasource_name === get_node_field_value($dashboard,'field_dashboard_datasource') ) { $dashboards[$key] = $dashboard; } } } reset($datasources); reset($dashboards); // sort the dashboard list by name usort($dashboards, function($a, $b) { if (strtolower($a->title) === strtolower($b->title)){ return strnatcmp($a->title,$b->title); } return strnatcasecmp($a->title,$b->title); }); // which dashboard to display if ( $current_dashboard ) { $dashboard = $current_dashboard; } else if (!empty($dashboards) ) { $dashboard = $dashboards[0]; } else { $dashboard = null; } $display_dashboards = array(); if ( !empty($dashboards) ) { $dashboard_ids = array(); // index of any parents from $dashboards $drilldown_dashboard_ids = array(); foreach ( $dashboards as $d ) { $config = new GD_DashboardConfig($d); $dashboard_ids[] = (int)$d->nid; foreach( $config->drilldowns as $drilldown) { if ( is_object($drilldown->dashboard) ) { $drilldown_dashboard_ids[] = (int)$drilldown->dashboard->id; // for backwards compatibility } else { $drilldown_dashboard_ids[] = (int)$drilldown->dashboard; } } } $drilldown_dashboard_ids = array_unique($drilldown_dashboard_ids); $display_dashboard_ids = array_diff($dashboard_ids, $drilldown_dashboard_ids); $display_dashboards = array(); foreach ( $dashboards as $d ) { if ( in_array($d->nid,$display_dashboard_ids) ) { $display_dashboards[] = $d; } } // if initial dashboard is a drilldown dashboard, load first non-drilldown dashboard instead if ( in_array($dashboard->nid, $drilldown_dashboard_ids) && empty($_GET['id']) ) { $dashboardKeys = array_keys($display_dashboard_ids); $dashboard = $dashboards[array_shift($dashboardKeys)]; } } // force a dashboard id into the url for javascript libs // TODO doing a redirect is wasteful, find some other way if ( empty($_GET['id']) && isset($dashboard) ) { drupal_goto('dashboards',array('query'=>array('id'=>$dashboard->nid))); } foreach ( $datasources as $k => $ds ) { if ( $ds->name == gd_datasource_get_active() ) { $datasources[$k]->active = true; } } return array($datasources, $dashboard, $display_dashboards); }
public function export(Export\ExportStream $stream, Export\ExportContext $context) { $datasource = gd_datasource_get_active(); $readOnly = gd_datasource_is_property($datasource, 'readonly'); if ($readOnly) { return; } $metamodel = data_controller_get_metamodel(); // get reference points that have ref to the dataset in this datamart $datasetNames = array(); foreach ( $stream->get('datasets') as $d ) { $datasetNames[] = $d->name; } $referencePoints = array(); $referencePointNodes = gd_reference_get_reference_points_by_dataset($datasetNames, LOAD_ENTITY); $referencePointNids = array(); foreach ( $referencePointNodes as $ref_point ) { $export = new stdClass(); $export->id = (int) $ref_point->nid; $export->title = $ref_point->title; $dataset = $metamodel->getDataset(get_node_field_value($ref_point,'field_ref_point_dataset_sysname',0,'value',true)); $export->dataset = $dataset->uuid; $export->columns = array(); foreach ( (array) get_node_field_value($ref_point,'field_ref_point_column_sysname',null) as $column ) { $export->columns[] = $column; } $referencePoints[] = $export; $referencePointNids[] = (int) $ref_point->nid; } // find all references with above reference points $references = array(); $referenceNodes = gd_reference_get_references_by_reference_points($referencePointNids, LOAD_ENTITY); foreach ( $referenceNodes as $reference ) { $export = new stdClass(); $export->id = (int) $reference->nid; $export->title = $reference->title; $export->sysname = get_node_field_value($reference,'field_reference_sysname'); foreach ( (array) get_node_field_node_ref($reference,'field_reference_point',null) as $referencePointNid ) { foreach ( $referencePoints as $referencePoint ){ if ( $referencePointNid == $referencePoint->id ) { $export->referencePoints[] = $referencePoint; } } } if ( empty($export->referencePoints) ) { throw new Exception('Reference missing reference points.'); } $references[] = $export; } $stream->set('references',$references); }
protected function getDataTableScript( $tableId, $scrollHeight, $tableSummary = '', $admin = TRUE, $public = FALSE, $external = FALSE, $sorting = null ) { $datasourceName = $this->ReportConfig->getNode() != null ? get_node_field_value($this->ReportConfig->getNode(), 'field_report_datasource') : null; if (!isset($datasourceName)) { $datasourceName = gd_datasource_get_active(); } // We can't use repeating background images because IE 9 does not reliably print them $overlay = gd_datasource_is_property($datasourceName, 'draft') ? '$("#' . $tableId . '").dataTable().fnSettings().aoDrawCallback.push({ "fn": function () { if ($("#' . $tableId . '").width() > $("#' . $tableId . '_wrapper > .table-content").width()) { $("#report-'.intval($this->ReportConfig->getId()).'-overlay").height($("#' . $tableId . '_wrapper > .table-content").height() - 14); } if ($("#' . $tableId . '").height() > $("#' . $tableId . '_wrapper > .table-content").height()) { $("#report-'.intval($this->ReportConfig->getId()).'-overlay").width($("#' . $tableId . '_wrapper > .table-content").width() - 14); } // Table is taller than the actual image forcing us to manually repeat the image if ($("#' . $tableId . '_wrapper > .table-content").height() > 1008) { var diff = $("#' . $tableId . '").height() - 1008; var num = Math.ceil(diff/1008); for (var i = 1; i <= num; i++) { $("#' . $tableId . '_wrapper").append($(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\').css("top", (1008 * i) + "px")); } } else if ($("#' . $tableId . '_wrapper > .table-content").width() > 1080) { var diff = $("#' . $tableId . '").width() - 1008; var num = Math.ceil(diff/1008); for (var i = 1; i <= num; i++) { $("#' . $tableId . '_wrapper").append($(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\').css("left", (1008 * i) + "px")); } } } }); $("#' . $tableId . '_wrapper").append(\'<img alt="Draft Overlay" title="Draft Overlay" aria-label="Draft Overlay" id="report-'.intval($this->ReportConfig->getId()).'-overlay" class="report-draft-overlay" src="/sites/all/modules/custom/report/includes/images/draft.png"/>\'); $("#report-'.intval($this->ReportConfig->getId()).'-overlay").bind("mouseenter mouseleave click dblclick focusout hover mousedown mousemove mouseout mouseover mouseup", function (e) { if (navigator.appName == "Microsoft Internet Explorer") { jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").hide(); var target = document.elementFromPoint(e.clientX, e.clientY); if (jQuery(target).is("a") && jQuery(target).attr("href") != "#" && e.type == "click") { window.location = jQuery(target).attr("href"); } jQuery(target).trigger(e.type); jQuery("#report-'.intval($this->ReportConfig->getId()).'-overlay").show(); } });' : ''; /* * TODO Move to actual JS file * For right now this has to kept in PHP due to how report render is done. * The JS below needs report configuration data (tableID, scrollHeight, etc.) for the table; * which means that to move this to a separate JS file, we need to send back * the raw table HTML + the configuration information that the JS needs, which * isn't done right now. */ $dataTableScript = '<script type="text/javascript"> (function (global) { !function($,undefined) { var func = function() { $("#report-' . intval($this->ReportConfig->getId()) . '").on("ready.report.render", function() { if ($.fn.DataTable.isDataTable("#' . $tableId . '"))' . (!$admin ? ('return;') : '$("#' . $tableId . '").dataTable().fnDestroy();') . ' var ROWS_PER_PAGE = ' . (GD_TABLE_ROWS_PER_PAGE) . '; var dashboardId = $("#dash_viewer").attr("dashboard_id"); //$.fn.dataTableExt.sErrMode = "throw"; var sortable = []; var sortableColumns = []; $("#' . $tableId . '").find("th").each(function () { if ( $(this).attr("column-name").indexOf("measure") != -1 ) { sortableColumns[$(this).attr("column-index")] = true; } else if ( $(this).attr("column-name").indexOf("column") != -1 ) { sortableColumns[$(this).attr("column-index")] = false; } else { sortableColumns[$(this).attr("column-index")] = null; } }); var disableMeasures = $.inArray(true, sortableColumns) != -1 && $.inArray(false, sortableColumns) != -1; if ( disableMeasures ) { $.each(sortableColumns, function (i, v) { if ( v === true ) { sortable.push( {"bSortable": false} ); } else { sortable.push(null); } }); } else { $.each(sortableColumns, function (i, v) { sortable.push(null); }); } $("#' . $tableId . '").dataTable({ "sDom": \'<"clear-table clearfix"i><"table-content"rt><"table-paging clearfix"p>\', "bServerSide": true, "bProcessing": true, "aoColumns": sortable, ' . (isset($sorting) ? '"aaSorting": ' . $sorting . ',' : '') . ' "iDisplayLength": ROWS_PER_PAGE, "oLanguage": { "sInfo": "Showing _START_ to _END_ of _TOTAL_ records", "sProcessing": "<div class=\"ldng datatableProcessing\"></div>" }, "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) { var page = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength); var orderBys = []; $.each(oSettings.aaSorting, function(i, sorting) { var sortedColumn = sorting[0]; var columnName = $("#' . $tableId . ' > thead > tr > th[column-index=" + sortedColumn + "]").attr("sort-column"); orderBys.push({ "column": columnName, "order": sorting[1] }); }); oSettings.jqXHR = $.ajax({ "dataType": ' . ($external ? '"jsonp"' : '"json"') . ', "type": "' . ($admin ? "POST" : "GET") . '", "url": "' . ($this->getCallbackUrl($admin, $public, $external)) . '", "data": { ' . $this->getServerArgs($admin) . ', "orderBy": orderBys, "offset": page * ROWS_PER_PAGE, "limit": ROWS_PER_PAGE }, "beforeSend": function(xhr, settings) { xhr.setRequestHeader("X-CSRF-Token",((typeof GovDashboard !== "undefined")? GovDashboard.token : GD.options.csrf)); }, "success": function (data) { if ($("#' . $tableId . '").length) { var json = {}; if (data["code"] == null || data["code"] == 200) { $.each(aoData, function (i, o) { if ( o["name"] == "sEcho" ) { json.sEcho = o["value"]; return false; } }); json.iTotalDisplayRecords = data["response"]["totalRows"]; json.iTotalRecords = data["response"]["totalRows"]; json.aaData = []; var columns = []; for ( var i = 0; i < oSettings.aoColumns.length; i++ ) { columns.push($("#' . $tableId . ' > thead > tr > th[column-index=\'" + i + "\']").attr("column-name")); } $.each(data["response"]["data"], function (i, r) { var row = r["record"]; var obj = []; $.each(columns, function (i, c) { obj.push(row[c]); }); json.aaData.push(obj); }); $("#' . $tableId . '_wrapper").find("th").attr("title", function () { return "Click to sort column"; }); if (data["response"]["totalRows"] > json.aaData.length) { var height = $("#' . $tableId . '_wrapper > div.table-content").css("height"); $("#' . $tableId . '_wrapper > div.table-content").css("height", ' . $scrollHeight . ' - 45 - $("#gd-report-footer-' . intval($this->ReportConfig->getId()) . '").height()); $("#' . $tableId . '_wrapper").find("div.dataTables_paginate").css("line-height", 0); $("#' . $tableId . '_wrapper > div.table-paging").find("a").attr("tabindex", "3000"); } else { $("#' . $tableId . '_wrapper > div.table-content").css("height", ' . $scrollHeight . ' - $("#gd-report-footer-' . intval($this->ReportConfig->getId()) . '").height()); $("#' . $tableId . '_wrapper > div.table-paging").hide(); } $("#' . $tableId . '_wrapper > div.table-content").find("thead").addClass("gd-table-header"); $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("scope", "col"); $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("tabindex", "3000"); $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("role"); $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("aria-live"); $("#' . $tableId . '_wrapper > div.table-content").find("tbody").removeAttr("aria-relevant"); ' . ((!isset($this->ReportConfig->options['visual']['advTableDisplayHeader'])) || $this->ReportConfig->options['visual']['advTableDisplayHeader'] === TRUE ? '' : '$("#' . $tableId . '_wrapper > div.table-content").find("thead").hide();') . ' fnCallback(json); $("#' . $tableId . '_wrapper > div.table-content").find("th").attr("title", function() { return $(this).attr("column-title") + ": activate to sort column " + ($(this).hasClass("sorting_desc") ? "descending" : "ascending"); }); $("#' . $tableId . '_wrapper > div.table-paging").find("li.paginate_button, a").attr("tabindex", "3000"); //$("div.dataTables_info").show(); } else if(data["code"] == 500) { $("#' . $tableId . '").dataTable().fnSettings().oLanguage.sEmptyTable = "There was an error retrieving table data. Please contact the site administrator."; $("#' . $tableId . '").dataTable().fnDraw(); } } } }).fail(function (jqXHR, textStatus, errorThrown) { ' . ($admin ? $this->getAdminError() : '') . ' }); } }); $("#' . $tableId . '_wrapper > .table-content").css("width", "100%"); $("#' . $tableId . '_wrapper > .table-content").attr("tabindex", "3000"); $("#' . $tableId . '_wrapper > .table-content").css("overflow", "auto"); $("#' . $tableId . '_wrapper > div.table-content > table").attr("summary", "' . $tableSummary . '"); ' . $overlay . ' }); }; ' . (!$external ? ('func();') : ('GD.ExecuteTable' . intval($this->ReportConfig->getId()) . ' = func;')) . ' }(global.GD_jQuery ? global.GD_jQuery : jQuery); })(!window ? this : window); </script>' ; return $dataTableScript; }
" }; global.GD.PivotTableFactory.createTable(<?php echo $reportId; ?> , "#report-<?php echo $reportId; ?> ", { measures: <?php echo json_encode($measures); ?> , draft: <?php echo gd_datasource_is_property(gd_datasource_get_active(), 'draft') ? "true" : "false"; ?> , rows: <?php echo isset($rows) ? json_encode($rows) : '[]'; ?> , cols: <?php echo isset($cols) ? json_encode($cols) : '[]'; ?> , columns: <?php echo json_encode($columns); ?> , url: urlOptions,