diff --git a/pandora_console/extras/mr/66.sql b/pandora_console/extras/mr/66.sql
index 376a725662..b0022d31b0 100644
--- a/pandora_console/extras/mr/66.sql
+++ b/pandora_console/extras/mr/66.sql
@@ -1,5 +1,13 @@
START TRANSACTION;
+CREATE TABLE IF NOT EXISTS `tgraph_analytics_filter` (
+`id` INT NOT NULL auto_increment,
+`filter_name` VARCHAR(45) NULL,
+`user_id` VARCHAR(255) NULL,
+`graph_modules` TEXT NULL,
+`interval` INT NULL,
+PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
UPDATE `twelcome_tip`
SET title = 'Scheduled downtimes',
diff --git a/pandora_console/images/draggable.svg b/pandora_console/images/draggable.svg
new file mode 100644
index 0000000000..3889fef861
--- /dev/null
+++ b/pandora_console/images/draggable.svg
@@ -0,0 +1,10 @@
+
diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php
index e8d4eb3a4f..889e32f693 100644
--- a/pandora_console/include/constants.php
+++ b/pandora_console/include/constants.php
@@ -807,6 +807,7 @@ define('AUDIT_LOG_FILE_MANAGER', 'File manager');
define('AUDIT_LOG_ALERT_MANAGEMENT', 'Alert management');
define('AUDIT_LOG_ALERT_CORRELATION_MANAGEMENT', 'Alert correlation management');
define('AUDIT_LOG_VISUAL_CONSOLE_MANAGEMENT', 'Visual Console Management');
+define('AUDIT_LOG_GRAPH_ANALYTICS_PUBLIC', 'Graph Analytics Public');
define('AUDIT_LOG_TAG_MANAGEMENT', 'Tag management');
define('AUDIT_LOG_SNMP_MANAGEMENT', 'SNMP management');
define('AUDIT_LOG_DASHBOARD_MANAGEMENT', 'Dashboard management');
diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php
index 4fa87f70cb..0895325ef5 100644
--- a/pandora_console/include/functions.php
+++ b/pandora_console/include/functions.php
@@ -270,7 +270,8 @@ function format_for_graph(
$dec_point='.',
$thousands_sep=',',
$divider=1000,
- $sufix=''
+ $sufix='',
+ $two_lines=false
) {
// Exception to exclude modules whose unit is already formatted as KB (satellite modules)
if (!empty($sufix) && $sufix == 'KB') {
@@ -297,6 +298,10 @@ function format_for_graph(
}
// This will actually do the rounding and the decimals.
+ if ($two_lines === true) {
+ return remove_right_zeros(format_numeric($number, $decimals)).'
'.$shorts[$pos].$sufix;
+ }
+
return remove_right_zeros(format_numeric($number, $decimals)).$shorts[$pos].$sufix;
}
@@ -4046,25 +4051,49 @@ function series_type_graph_array($data, $show_elements_graph)
}
} else {
$name_legend = '';
- if (isset($show_elements_graph['fullscale']) === true
- && (int) $show_elements_graph['fullscale'] === 1
- ) {
- $name_legend .= 'Tip: ';
- } else {
- $name_legend .= 'Avg: ';
- }
- if ($value['unit']) {
- $name_legend .= $value['agent_alias'];
- $name_legend .= ' / ';
- $name_legend .= $value['module_name'];
- $name_legend .= ' / ';
- $name_legend .= __('Unit ').' ';
- $name_legend .= $value['unit'].': ';
+ if ($show_elements_graph['graph_analytics'] === true) {
+ $name_legend .= '
';
+ $name_legend .= '
';
+ $name_legend .= '';
+ $name_legend .= format_for_graph(
+ end(end($value['data'])),
+ 1,
+ $config['decimal_separator'],
+ $config['thousand_separator'],
+ 1000,
+ '',
+ true
+ );
+ $name_legend .= '';
+ $name_legend .= ''.$value['unit'].'';
+ $name_legend .= '
';
+ $name_legend .= '
';
+ $name_legend .= ''.$value['agent_alias'].'';
+ $name_legend .= ''.$value['module_name'].'';
+ $name_legend .= '
';
+ $name_legend .= '
';
} else {
- $name_legend .= $value['agent_alias'];
- $name_legend .= ' / ';
- $name_legend .= $value['module_name'].': ';
+ if (isset($show_elements_graph['fullscale']) === true
+ && (int) $show_elements_graph['fullscale'] === 1
+ ) {
+ $name_legend .= 'Tip: ';
+ } else {
+ $name_legend .= 'Avg: ';
+ }
+
+ if ($value['unit']) {
+ $name_legend .= $value['agent_alias'];
+ $name_legend .= ' / ';
+ $name_legend .= $value['module_name'];
+ $name_legend .= ' / ';
+ $name_legend .= __('Unit ').' ';
+ $name_legend .= $value['unit'].': ';
+ } else {
+ $name_legend .= $value['agent_alias'];
+ $name_legend .= ' / ';
+ $name_legend .= $value['module_name'].': ';
+ }
}
}
}
@@ -4085,28 +4114,30 @@ function series_type_graph_array($data, $show_elements_graph)
$value['max'] = 0;
}
- $data_return['legend'][$key] .= ''.__('Min').' '.remove_right_zeros(
- number_format(
- $value['min'],
- $config['graph_precision'],
- $config['csv_decimal_separator'],
- $config['csv_decimal_separator'] == ',' ? '.' : ','
- )
- ).' '.$value['unit'].' '.__('Max').' '.remove_right_zeros(
- number_format(
- $value['max'],
- $config['graph_precision'],
- $config['csv_decimal_separator'],
- $config['csv_decimal_separator'] == ',' ? '.' : ','
- )
- ).' '.$value['unit'].' '._('Avg.').' '.remove_right_zeros(
- number_format(
- $value['avg'],
- $config['graph_precision'],
- $config['csv_decimal_separator'],
- $config['csv_decimal_separator'] == ',' ? '.' : ','
- )
- ).' '.$value['unit'].' '.$str;
+ if (isset($show_elements_graph['graph_analytics']) === false) {
+ $data_return['legend'][$key] .= ''.__('Min').' '.remove_right_zeros(
+ number_format(
+ $value['min'],
+ $config['graph_precision'],
+ $config['csv_decimal_separator'],
+ $config['csv_decimal_separator'] == ',' ? '.' : ','
+ )
+ ).' '.$value['unit'].' '.__('Max').' '.remove_right_zeros(
+ number_format(
+ $value['max'],
+ $config['graph_precision'],
+ $config['csv_decimal_separator'],
+ $config['csv_decimal_separator'] == ',' ? '.' : ','
+ )
+ ).' '.$value['unit'].' '._('Avg.').' '.remove_right_zeros(
+ number_format(
+ $value['avg'],
+ $config['graph_precision'],
+ $config['csv_decimal_separator'],
+ $config['csv_decimal_separator'] == ',' ? '.' : ','
+ )
+ ).' '.$value['unit'].' '.$str;
+ }
if ($show_elements_graph['compare'] == 'overlapped'
&& $key == 'sum2'
diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php
index 1892b0cd31..6fa1e2a8d5 100644
--- a/pandora_console/include/functions_graph.php
+++ b/pandora_console/include/functions_graph.php
@@ -5540,3 +5540,23 @@ function graph_events_agent_by_group($id_group, $width=300, $height=200, $noWate
$options
);
}
+
+
+function graph_analytics_filter_select()
+{
+ global $config;
+
+ $result = [];
+
+ if (check_acl($config['id_user'], 0, 'RW') === 1 || check_acl($config['id_user'], 0, 'RM') === 1) {
+ $filters = db_get_all_rows_sql('SELECT id, filter_name FROM tgraph_analytics_filter WHERE user_id = "'.$config['id_user'].'"');
+
+ if ($filters !== false) {
+ foreach ($filters as $filter) {
+ $result[$filter['id']] = $filter['filter_name'];
+ }
+ }
+ }
+
+ return $result;
+}
diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php
index 13d984eba6..e1c04a45b5 100755
--- a/pandora_console/include/functions_ui.php
+++ b/pandora_console/include/functions_ui.php
@@ -4511,7 +4511,8 @@ function ui_toggle(
$switch_on=null,
$switch_name=null,
$disableToggle=false,
- $id_table=false
+ $id_table=false,
+ $position_tgl_div=false
) {
// Generate unique Id.
$uniqid = uniqid('');
@@ -4630,6 +4631,11 @@ function ui_toggle(
}
if ($disableToggle === false) {
+ $position_div = 'relative';
+ if ($position_tgl_div !== false) {
+ $position_div = $position_tgl_div;
+ }
+
// JQuery Toggle.
$output .= '
+ ";
+
+ echo $graph_return;
+ return;
+ }
+
+ // Save filter.
+ if (empty($save_filter) === false) {
+ $graphs = get_parameter('graphs');
+ $interval = (int) get_parameter('interval');
+
+ if (empty($save_filter) === true) {
+ echo __('Empty name');
+ return;
+ }
+
+ if (empty($graphs) === true) {
+ echo __('It is not possible to create the filter if you have not made any change');
+ return;
+ }
+
+ $id_filter = db_process_sql_insert(
+ 'tgraph_analytics_filter',
+ [
+ 'filter_name' => $save_filter,
+ 'user_id' => $config['id_user'],
+ 'graph_modules' => json_encode($graphs),
+ 'interval' => $interval,
+ ]
+ );
+
+ if ($id_filter > 0) {
+ echo 'saved';
+ return;
+ } else {
+ echo __('It is not possible to create the filter if you have not made any change');
+ return;
+ }
+ }
+
+ // Update filter.
+ if (empty($update_filter) === false) {
+ $graphs = get_parameter('graphs');
+ $interval = (int) get_parameter('interval');
+
+ if (empty($graphs) === true) {
+ echo __('It is not possible to update the filter if you have not made any change');
+ return;
+ }
+
+ $update_filter = db_process_sql_update(
+ 'tgraph_analytics_filter',
+ [
+ 'graph_modules' => json_encode($graphs),
+ 'interval' => $interval,
+ ],
+ ['id' => $update_filter]
+ );
+
+ if ($update_filter > 0) {
+ echo 'updated';
+ return;
+ } else {
+ echo __('No updated');
+ return;
+ }
+
+ echo $update_filter;
+ return;
+ }
+
+ // Load filter.
+ if (empty($load_filter) === false) {
+ $data = [];
+ $data['graphs'] = json_decode(db_get_value('graph_modules', 'tgraph_analytics_filter', 'id', $load_filter));
+ $data['interval'] = db_get_value('tgraph_analytics_filter.interval', 'tgraph_analytics_filter', 'id', $load_filter);
+
+ echo json_encode($data);
+ return;
+ }
+
+ // Get new values.
+ if (empty($get_new_values) === false) {
+ $data = [];
+
+ $agent_module_id = $get_new_values;
+ $date_array = get_parameter('date_array');
+ $data_module_graph = get_parameter('data_module_graph');
+ $params = get_parameter('params');
+ $suffix = get_parameter('suffix');
+
+ // Stract data.
+ $array_data_module = grafico_modulo_sparse_data(
+ $agent_module_id,
+ $date_array,
+ $data_module_graph,
+ $params,
+ $suffix
+ );
+
+ echo json_encode($array_data_module);
+ return;
+ }
+
+ // Export graphs.
+ if (empty($export_filter) === false) {
+ $counter = 0;
+ $filter = get_parameter('export_filter');
+ $group = get_parameter('group');
+
+ $filter_name = db_get_value('filter_name', 'tgraph_analytics_filter', 'id', $filter);
+ $graphs = json_decode(db_get_value('graph_modules', 'tgraph_analytics_filter', 'id', $filter));
+ $interval = db_get_value('tgraph_analytics_filter.interval', 'tgraph_analytics_filter', 'id', $filter);
+
+ foreach ($graphs as $graph) {
+ $id_graph = db_process_sql_insert(
+ 'tgraph',
+ [
+ 'id_user' => $config['id_user'],
+ 'id_group' => $group,
+ 'name' => $filter_name.' ('.__('Graph').' '.($counter + 1).')',
+ 'description' => __('Created from Graph analytics. Filter:').' '.$filter_name.'. '.__('Graph').' '.($counter + 1),
+ 'period' => $interval,
+ 'stacked' => 2,
+ ]
+ );
+
+ if ($id_graph > 0) {
+ $counter++;
+ $field_order = 1;
+
+ foreach ($graph as $module) {
+ $id_graph_source = db_process_sql_insert(
+ 'tgraph_source',
+ [
+ 'id_graph' => $id_graph,
+ 'id_server' => 0,
+ 'id_agent_module' => $module,
+ 'weight' => 1,
+ 'label' => '',
+ 'field_order' => $field_order,
+ ]
+ );
+
+ $field_order++;
+ }
+ }
+ }
+
+ echo $counter;
+ }
+
+ return;
+}
+
+// Save filter modal.
+echo '';
+if (check_acl($config['id_user'], 0, 'RW') === 1 || check_acl($config['id_user'], 0, 'RM') === 1) {
+ echo '
';
+ $table = new StdClass;
+ $table->id = 'save_filter_form';
+ $table->width = '100%';
+ $table->cellspacing = 4;
+ $table->cellpadding = 4;
+ $table->class = 'databox no_border';
+
+ $table->styleTable = 'font-weight: bold; text-align:left;';
+
+ $data = [];
+ $table->rowid[0] = 'update_save_selector';
+ $data[0] = html_print_div(
+ [
+ 'style' => 'display: flex;',
+ 'content' => html_print_radio_button(
+ 'filter_mode',
+ 'new',
+ __('New filter'),
+ true,
+ true
+ ),
+ ],
+ true
+ );
+
+ $data[1] = html_print_div(
+ [
+ 'style' => 'display: flex;',
+ 'content' => html_print_radio_button(
+ 'filter_mode',
+ 'update',
+ __('Update filter'),
+ false,
+ true
+ ),
+ ],
+ true
+ );
+
+ $table->data[] = $data;
+ $table->rowclass[] = '';
+
+ $data = [];
+ $table->rowid[1] = 'save_filter_row1';
+ $data[0] = __('Filter name');
+ $data[0] .= html_print_input_text('id_name', '', '', 15, 255, true);
+
+ $data[1] = html_print_submit_button(
+ __('Save filter'),
+ 'save_filter',
+ false,
+ [
+ 'class' => 'mini ',
+ 'icon' => 'save',
+ 'style' => 'margin-left: 175px; width: 125px;',
+ 'onclick' => 'save_new_filter();',
+ ],
+ true
+ );
+
+ $table->data[] = $data;
+ $table->rowclass[] = '';
+
+ $data = [];
+ $table->rowid[2] = 'save_filter_row2';
+
+ $table->data[] = $data;
+ $table->rowclass[] = '';
+
+ $data = [];
+ $table->rowid[3] = 'update_filter_row1';
+ $data[0] = __('Overwrite filter');
+
+ $select_filters_update = graph_analytics_filter_select();
+
+ $data[0] .= html_print_select(
+ $select_filters_update,
+ 'overwrite_filter',
+ '',
+ '',
+ '',
+ 0,
+ true
+ );
+ $table->rowclass[] = 'display-grid';
+ $data[1] = html_print_submit_button(
+ __('Update filter'),
+ 'update_filter',
+ false,
+ [
+ 'class' => 'mini ',
+ 'icon' => 'save',
+ 'style' => 'margin-left: 155px; width: 145px;',
+ 'onclick' => 'save_update_filter();',
+ ],
+ true
+ );
+
+ $table->data[] = $data;
+ $table->rowclass[] = '';
+
+ html_print_table($table);
+} else {
+ include 'general/noaccess.php';
+}
+
+echo '
';
+
+// Load filter modal.
+$filters = graph_analytics_filter_select();
+
+echo '';
+
+$table = new StdClass;
+$table->id = 'load_filter_form';
+$table->width = '100%';
+$table->cellspacing = 4;
+$table->cellpadding = 4;
+$table->class = 'databox no_border';
+
+$table->styleTable = 'font-weight: bold; color: #555; text-align:left;';
+$filter_id_width = 'w100p';
+
+$data = [];
+$table->rowid[3] = 'update_filter_row1';
+$data[0] = __('Load filter');
+$data[0] .= html_print_select(
+ $filters,
+ 'filter_id',
+ '',
+ '',
+ __('None'),
+ 0,
+ true,
+ false,
+ true,
+ '',
+ false,
+ 'width:'.$filter_id_width.';'
+);
+
+$table->rowclass[] = 'display-grid';
+$data[1] = html_print_submit_button(
+ __('Load filter'),
+ 'load_filter',
+ false,
+ [
+ 'class' => 'mini w30p',
+ 'icon' => 'load',
+ 'style' => 'margin-left: 208px; width: 130px;',
+ 'onclick' => 'load_filter_values();',
+ ],
+ true
+);
+$data[1] .= html_print_input_hidden('load_filter', 1, true);
+$table->data[] = $data;
+$table->rowclass[] = '';
+
+html_print_table($table);
+echo '
';
+
+// Share modal.
+echo '';
+
+$table = new StdClass;
+$table->id = 'share_form';
+$table->width = '100%';
+$table->cellspacing = 4;
+$table->cellpadding = 4;
+$table->class = 'databox no_border';
+
+$table->styleTable = 'font-weight: bold; color: #555; text-align:left;';
+$filter_id_width = 'w100p';
+
+$data = [];
+$table->rowid[3] = 'share_row1';
+$data[0] = __('Share');
+$data[0] .= html_print_select(
+ $filters,
+ 'share-id',
+ '',
+ '',
+ '',
+ 0,
+ true,
+ false,
+ true,
+ '',
+ false,
+ 'width:'.$filter_id_width.';'
+);
+
+$table->rowclass[] = 'display-grid';
+$data[1] = html_print_submit_button(
+ __('Share'),
+ 'share-modal',
+ false,
+ [
+ 'class' => 'mini w30p',
+ 'icon' => 'next',
+ 'style' => 'margin-left: 208px; width: 130px;',
+ 'onclick' => '',
+ ],
+ true
+);
+$data[1] .= html_print_input_hidden('share-hidden', 1, true);
+$table->data[] = $data;
+$table->rowclass[] = '';
+
+html_print_table($table);
+echo '
';
+
+// Export graphs.
+echo '';
+
+$table = new StdClass;
+$table->id = 'share_form';
+$table->width = '100%';
+$table->cellspacing = 4;
+$table->cellpadding = 4;
+$table->class = 'databox no_border';
+
+$table->styleTable = 'font-weight: bold; color: #555; text-align:left;';
+$filter_id_width = 'w100p';
+
+$data = [];
+$table->rowid[3] = 'export_row1';
+$data[0] = __('Export filter');
+$data[0] .= html_print_select(
+ $filters,
+ 'export-filter-id',
+ '',
+ '',
+ '',
+ 0,
+ true,
+ false,
+ true,
+ '',
+ false,
+ 'width:'.$filter_id_width.';'
+);
+
+$user_groups = users_get_groups($config['user'], 'RW');
+$data[1] = __('Group');
+$data[1] .= html_print_select(
+ $user_groups,
+ 'export-group-id',
+ '',
+ '',
+ '',
+ 0,
+ true,
+ false,
+ true,
+ '',
+ false,
+ 'width:'.$filter_id_width.';'
+);
+
+$table->rowclass[] = 'display-grid';
+$data[2] = html_print_submit_button(
+ __('Export'),
+ 'export-modal',
+ false,
+ [
+ 'class' => 'mini w30p',
+ 'icon' => 'next',
+ 'style' => 'margin-left: 208px; width: 130px;',
+ 'onclick' => '',
+ ],
+ true
+);
+$data[1] .= html_print_input_hidden('export-hidden', 1, true);
+$table->data[] = $data;
+$table->rowclass[] = '';
+
+html_print_table($table);
+echo '
';
+
+
+// Header & Actions.
+$title_tab = __('Start realtime');
+$tab_start_realtime = [
+ 'text' => ''.html_print_image(
+ 'images/change-active.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+$title_tab = __('Pause realtime');
+$tab_pause_realtime = [
+ 'text' => ''.html_print_image(
+ 'images/change-pause.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+$title_tab = __('New');
+$tab_new = [
+ 'text' => ''.html_print_image(
+ 'images/plus-black.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+$title_tab = __('Save');
+$tab_save = [
+ 'text' => ''.html_print_image(
+ 'images/save_mc.png',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+$title_tab = __('Load');
+$tab_load = [
+ 'text' => ''.html_print_image(
+ 'images/logs@svg.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+// Hash for auto-auth in public link.
+$hash = User::generatePublicHash();
+
+$title_tab = __('Share');
+$tab_share = [
+ 'text' => ''.html_print_image(
+ 'images/responses.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'
+ ',
+];
+
+$title_tab = __('Export to custom graph');
+$tab_export = [
+ 'text' => ''.html_print_image(
+ 'images/module-graph.svg',
+ true,
+ [
+ 'title' => $title_tab,
+ 'class' => 'invert_filter main_menu_icon',
+ ]
+ ).$title_tab.'',
+];
+
+ui_print_standard_header(
+ __('Graph analytics'),
+ 'images/menu/reporting.svg',
+ false,
+ '',
+ false,
+ [
+ $tab_export,
+ $tab_share,
+ $tab_load,
+ $tab_save,
+ $tab_new,
+ $tab_pause_realtime,
+ $tab_start_realtime,
+ ],
+ [
+ [
+ 'link' => '',
+ 'label' => __('Reporting'),
+ ],
+ ]
+);
+
+// Content.
+$left_content = '';
+$right_content = '';
+
+$left_content .= '
+
+
+
+
+
+'.ui_toggle(
+ '',
+ __('Agents'),
+ 'agents-toggle',
+ 'agents-toggle',
+ true,
+ true,
+ '',
+ 'white-box-content',
+ 'box-flat white_table_graph',
+ 'images/arrow@svg.svg',
+ 'images/arrow@svg.svg',
+ false,
+ false,
+ false,
+ '',
+ '',
+ null,
+ null,
+ false,
+ false,
+ 'static'
+).ui_toggle(
+ '',
+ __('Groups'),
+ 'groups-toggle',
+ 'groups-toggle',
+ true,
+ true,
+ '',
+ 'white-box-content',
+ 'box-flat white_table_graph',
+ 'images/arrow@svg.svg',
+ 'images/arrow@svg.svg',
+ false,
+ false,
+ false,
+ '',
+ '',
+ null,
+ null,
+ false,
+ false,
+ 'static'
+).ui_toggle(
+ '',
+ __('Modules'),
+ 'modules-toggle',
+ 'modules-toggle',
+ true,
+ true,
+ '',
+ 'white-box-content',
+ 'box-flat white_table_graph',
+ 'images/arrow@svg.svg',
+ 'images/arrow@svg.svg',
+ false,
+ false,
+ false,
+ '',
+ '',
+ null,
+ null,
+ false,
+ false,
+ 'static'
+).'
+
+
+
+';
+
+$intervals = [];
+$intervals[SECONDS_1HOUR] = _('Last ').human_time_description_raw(SECONDS_1HOUR, true, 'large');
+$intervals[SECONDS_6HOURS] = _('Last ').human_time_description_raw(SECONDS_6HOURS, true, 'large');
+$intervals[SECONDS_12HOURS] = _('Last ').human_time_description_raw(SECONDS_12HOURS, true, 'large');
+$intervals[SECONDS_1DAY] = _('Last ').human_time_description_raw(SECONDS_1DAY, true, 'large');
+$intervals[SECONDS_2DAY] = _('Last ').human_time_description_raw(SECONDS_2DAY, true, 'large');
+$intervals[SECONDS_1WEEK] = _('Last ').human_time_description_raw(SECONDS_1WEEK, true, 'large');
+
+$right_content .= ''.html_print_select(
+ $intervals,
+ 'interval',
+ SECONDS_12HOURS,
+ '',
+ '',
+ 0,
+ true,
+ false,
+ false,
+ ''
+).'
';
+
+$right_content .= '
+
+';
+
+$filters_div = html_print_div(
+ [
+ 'class' => 'filters-div-main',
+ 'content' => $left_content,
+ ],
+ true
+);
+
+$graphs_div = html_print_div(
+ [
+ 'class' => 'padding-div graphs-div-main',
+ 'content' => $right_content,
+ ],
+ true
+);
+
+html_print_div(
+ [
+ 'class' => 'white_box main-div',
+ 'content' => $filters_div.$graphs_div,
+ ]
+);
+
+ui_require_javascript_file('graph_analytics', 'include/javascript/', true);
+?>
+
+
\ No newline at end of file
diff --git a/pandora_console/operation/reporting/graph_analytics_public.php b/pandora_console/operation/reporting/graph_analytics_public.php
new file mode 100644
index 0000000000..434bb89809
--- /dev/null
+++ b/pandora_console/operation/reporting/graph_analytics_public.php
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+ '.get_product_name().$text_subtitle.'
+';
+
+// CSS.
+ui_require_css_file('common', 'include/styles/', true);
+ui_require_css_file('pandora', 'include/styles/', true);
+ui_require_css_file('discovery', 'include/styles/', true);
+ui_require_css_file('register', 'include/styles/', true);
+ui_require_css_file('order_interpreter', 'include/styles/', true);
+ui_require_css_file('graph_analytics', 'include/styles/', true);
+ui_require_css_file('jquery-ui.min', 'include/styles/js/', true);
+ui_require_css_file('jquery-ui_custom', 'include/styles/js/', true);
+ui_require_css_file('introjs', 'include/styles/js/', true);
+ui_require_css_file('events', 'include/styles/', true);
+
+// JS.
+ui_require_javascript_file('jquery.current', 'include/javascript/', true);
+ui_require_javascript_file('jquery.pandora', 'include/javascript/', true);
+ui_require_javascript_file('jquery-ui.min', 'include/javascript/', true);
+ui_require_javascript_file('jquery.countdown', 'include/javascript/', true);
+ui_require_javascript_file('pandora', 'include/javascript/', true);
+ui_require_javascript_file('pandora_ui', 'include/javascript/', true);
+ui_require_javascript_file('pandora_events', 'include/javascript/', true);
+ui_require_javascript_file('select2.min', 'include/javascript/', true);
+// ui_require_javascript_file('connection_check', 'include/javascript/', true);
+ui_require_javascript_file('encode_decode_base64', 'include/javascript/', true);
+ui_require_javascript_file('qrcode', 'include/javascript/', true);
+ui_require_javascript_file('intro', 'include/javascript/', true);
+ui_require_javascript_file('clippy', 'include/javascript/', true);
+ui_require_javascript_file('underscore-min', 'include/javascript/', true);
+
+echo '
+
+';
+
+
+
+ui_require_javascript_file('date', 'include/javascript/timezone/src/', true);
+ui_require_javascript_file('jquery.flot.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.time', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.pie', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.crosshair.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.stack.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.selection.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.resize.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.threshold', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.threshold.multiple', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.symbol.min', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.exportdata.pandora', 'include/graphs/flot/', true);
+ui_require_javascript_file('jquery.flot.axislabels', 'include/graphs/flot/', true);
+ui_require_javascript_file('pandora.flot', 'include/graphs/flot/', true);
+ui_require_javascript_file('chart', 'include/graphs/chartjs/', true);
+ui_require_javascript_file('chartjs-plugin-datalabels.min', 'include/graphs/chartjs/', true);
+
+
+
+ui_require_javascript_file('graph_analytics', 'include/javascript/', true);
+
+
+echo '
+
+
+';
+
+// Content.
+$right_content = '';
+
+$right_content .= '
+
+';
+
+$graphs_div = html_print_div(
+ [
+ 'class' => 'padding-div graphs-div-main',
+ 'content' => $right_content,
+ ],
+ true
+);
+
+html_print_div(
+ [
+ 'class' => 'white_box main-div graph-analytics-public',
+ 'content' => $graphs_div,
+ ]
+);
+
+?>
+
+
+
+
+
\ No newline at end of file
diff --git a/pandora_console/pandoradb.sql b/pandora_console/pandoradb.sql
index 64d0b96813..9ddd3fafa0 100644
--- a/pandora_console/pandoradb.sql
+++ b/pandora_console/pandoradb.sql
@@ -4421,4 +4421,16 @@ CREATE TABLE IF NOT EXISTS `tsca` (
`remediation` text DEFAULT NULL,
`compliance` text DEFAULT NULL,
PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
+
+-- ---------------------------------------------------------------------
+-- Table `tgraph_analytics_filter`
+-- ---------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS `tgraph_analytics_filter` (
+`id` INT NOT NULL auto_increment,
+`filter_name` VARCHAR(45) NULL,
+`user_id` VARCHAR(255) NULL,
+`graph_modules` TEXT NULL,
+`interval` INT NULL,
+PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;
\ No newline at end of file