1<?php
2
3// Pandora FMS - http://pandorafms.com
4// ==================================================
5// Copyright (c) 2011 Artica Soluciones Tecnologicas
6// Please see http://pandorafms.org for full contribution list
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the  GNU Lesser General Public License
10// as published by the Free Software Foundation; version 2
11
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17include_once($config['homedir'] . "/include/graphs/fgraph.php");
18include_once($config['homedir'] . "/include/functions_reporting.php");
19include_once($config['homedir'] . "/include/functions_agents.php");
20include_once($config['homedir'] . "/include/functions_modules.php");
21include_once($config['homedir'] . "/include/functions_users.php");
22
23function get_graph_statistics ($chart_array) {
24
25	/// IMPORTANT!
26	///
27	/// The calculus for AVG, MIN and MAX values are in this function
28	/// because it must be done based on graph array data not using reporting
29	/// function to get coherent data between stats and graph visualization
30
31	$stats = array ();
32
33	$count = 0;
34
35	$size = sizeof($chart_array);
36
37	//Initialize stats array
38	$stats = array ("avg" => 0, "min" => null, "max" => null, "last" => 0);
39
40	foreach ($chart_array as $item) {
41
42		//Sum all values later divide by the number of elements
43		$stats['avg'] = $stats['avg'] + $item;
44
45		//Get minimum
46		if ($stats['min'] == null) {
47			$stats['min'] = $item;
48		}
49		else if ($item < $stats['min']) {
50			$stats['min'] = $item;
51		}
52
53		//Get maximum
54		if ($stats['max'] == null) {
55			$stats['max'] = $item;
56		}
57		else if ($item > $stats['max']) {
58			$stats['max'] = $item;
59		}
60
61		$count++;
62
63		//Get last data
64		if ($count == $size) {
65			$stats['last'] = $item;
66		}
67	}
68
69	//End the calculus for average
70	if ($count > 0) {
71
72		$stats['avg'] = $stats['avg'] / $count;
73	}
74
75	//Format stat data to display properly
76	$stats['last'] = round($stats['last'], 2);
77	$stats['avg'] = round($stats['avg'], 2);
78	$stats['min'] = round($stats['min'], 2);
79	$stats['max'] = round($stats['max'], 2);
80
81	return $stats;
82}
83
84function get_statwin_graph_statistics ($chart_array, $series_suffix = '') {
85
86	/// IMPORTANT!
87	///
88	/// The calculus for AVG, MIN and MAX values are in this function
89	/// because it must be done based on graph array data not using reporting
90	/// function to get coherent data between stats and graph visualization
91
92	$stats = array ();
93
94	$count = 0;
95
96	$size = sizeof($chart_array);
97
98	//Initialize stats array
99	$stats['sum'] = array ("avg" => 0, "min" => null, "max" => null, "last" => 0);
100	$stats['min'] = array ("avg" => 0, "min" => null, "max" => null, "last" => 0);
101	$stats['max'] = array ("avg" => 0, "min" => null, "max" => null, "last" => 0);
102
103	foreach ($chart_array as $item) {
104		if ($series_suffix != '') {
105			if (isset($item['sum' . $series_suffix]))
106				$item['sum'] = $item['sum' . $series_suffix];
107			if (isset($item['min' . $series_suffix]))
108				$item['min'] = $item['min' . $series_suffix];
109			if (isset($item['max' . $series_suffix]))
110				$item['max'] = $item['max' . $series_suffix];
111		}
112
113		//Get stats for normal graph
114		if (isset($item['sum']) && $item['sum']) {
115
116			//Sum all values later divide by the number of elements
117			$stats['sum']['avg'] = $stats['sum']['avg'] + $item['sum'];
118
119			//Get minimum
120			if ($stats['sum']['min'] == null) {
121				$stats['sum']['min'] = $item['sum'];
122			}
123			else if ($item['sum'] < $stats['sum']['min']) {
124				$stats['sum']['min'] = $item['sum'];
125			}
126
127			//Get maximum
128			if ($stats['sum']['max'] == null) {
129				$stats['sum']['max'] = $item['sum'];
130			}
131			else if ($item['sum'] > $stats['sum']['max']) {
132				$stats['sum']['max'] = $item['sum'];
133			}
134
135		}
136
137		//Get stats for min graph
138		if (isset($item['min']) && $item['min']) {
139			//Sum all values later divide by the number of elements
140			$stats['min']['avg'] = $stats['min']['avg'] + $item['min'];
141
142			//Get minimum
143			if ($stats['min']['min'] == null) {
144				$stats['min']['min'] = $item['min'];
145			}
146			else if ($item['min'] < $stats['min']['min']) {
147				$stats['min']['min'] = $item['min'];
148			}
149
150			//Get maximum
151			if ($stats['min']['max'] == null) {
152				$stats['min']['max'] = $item['min'];
153			}
154			else if ($item['min'] > $stats['min']['max']) {
155				$stats['min']['max'] = $item['min'];
156			}
157
158		}
159
160		//Get stats for max graph
161		if (isset($item['max']) && $item['max']) {
162			//Sum all values later divide by the number of elements
163			$stats['max']['avg'] = $stats['max']['avg'] + $item['max'];
164
165			//Get minimum
166			if ($stats['max']['min'] == null) {
167				$stats['max']['min'] = $item['max'];
168			}
169			else if ($item['max'] < $stats['max']['min']) {
170				$stats['max']['min'] = $item['max'];
171			}
172
173			//Get maximum
174			if ($stats['max']['max'] == null) {
175				$stats['max']['max'] = $item['max'];
176			}
177			else if ($item['max'] > $stats['max']['max']) {
178				$stats['max']['max'] = $item['max'];
179			}
180		}
181
182
183		//Count elements
184		$count++;
185
186		//Get last data
187		if ($count == $size) {
188			if (isset($item['sum']) && $item['sum']) {
189				$stats['sum']['last'] = $item['sum'];
190			}
191
192			if (isset($item['min']) && $item['min']) {
193				$stats['min']['last'] = $item['min'];
194			}
195
196			if (isset($item['max']) && $item['max']) {
197				$stats['max']['last'] = $item['max'];
198			}
199		}
200	}
201
202	//End the calculus for average
203	if ($count > 0) {
204
205		$stats['sum']['avg'] = $stats['sum']['avg'] / $count;
206		$stats['min']['avg'] = $stats['min']['avg'] / $count;
207		$stats['max']['avg'] = $stats['max']['avg'] / $count;
208	}
209
210	//Format stat data to display properly
211	$stats['sum']['last'] = round($stats['sum']['last'], 2);
212	$stats['sum']['avg'] = round($stats['sum']['avg'], 2);
213	$stats['sum']['min'] = round($stats['sum']['min'], 2);
214	$stats['sum']['max'] = round($stats['sum']['max'], 2);
215
216	$stats['min']['last'] = round($stats['min']['last'], 2);
217	$stats['min']['avg'] = round($stats['min']['avg'], 2);
218	$stats['min']['min'] = round($stats['min']['min'], 2);
219	$stats['min']['max'] = round($stats['min']['max'], 2);
220
221	$stats['max']['last'] = round($stats['max']['last'], 2);
222	$stats['max']['avg'] = round($stats['max']['avg'], 2);
223	$stats['max']['min'] = round($stats['max']['min'], 2);
224	$stats['max']['max'] = round($stats['max']['max'], 2);
225
226	return $stats;
227}
228
229function grafico_modulo_sparse_data_chart (&$chart, &$chart_data_extra, &$long_index,
230				$data, $data_i, $previous_data, $resolution, $interval, $period, $datelimit,
231				$projection, $avg_only = false, $uncompressed_module = false,
232				$show_events = false, $show_alerts = false, $show_unknown = false, $baseline = false,
233				$baseline_data = array(), $events = array(), $series_suffix = '', $start_unknown = false,
234				$percentil = null) {
235
236	global $config;
237	global $chart_extra_data;
238	global $series_type;
239	global $max_value;
240	global $min_value;
241
242	$max_value = 0;
243	$min_value = null;
244	$flash_chart = $config['flash_charts'];
245
246	// Event iterator
247	$event_i = 0;
248
249	// Is unknown flag
250	$is_unknown = $start_unknown;
251
252	// Calculate chart data
253	$last_known = $previous_data;
254
255
256	for ($i = 0; $i <= $resolution; $i++) {
257		$timestamp = $datelimit + ($interval * $i);
258
259
260		$total = 0;
261		$count = 0;
262
263		// Read data that falls in the current interval
264		$interval_min = false;
265		$interval_max = false;
266
267		while (isset ($data[$data_i]) && $data[$data_i]['utimestamp'] >= $timestamp && $data[$data_i]['utimestamp'] < ($timestamp + $interval)) {
268			if ($interval_min === false) {
269				$interval_min = $data[$data_i]['datos'];
270			}
271			if ($interval_max === false) {
272				$interval_max = $data[$data_i]['datos'];
273			}
274
275			if ($data[$data_i]['datos'] > $interval_max) {
276				$interval_max = $data[$data_i]['datos'];
277			}
278			else if ($data[$data_i]['datos'] < $interval_min) {
279				$interval_min = $data[$data_i]['datos'];
280			}
281			$total += $data[$data_i]['datos'];
282			$last_known = $data[$data_i]['datos'];
283			$count++;
284			$data_i++;
285		}
286
287		if ($max_value < $interval_max) {
288			$max_value = $interval_max;
289		}
290
291		if ($min_value > $interval_max || $min_value == null) {
292			$min_value = $interval_max;
293		}
294
295		// Data in the interval
296		if ($count > 0) {
297			$total /= $count;
298			// If detect data, unknown period finishes
299			$is_unknown = false;
300		}
301
302		// Read events and alerts that fall in the current interval
303		$event_value = 0;
304		$alert_value = 0;
305		$unknown_value = 0;
306		// Is the first point of a unknown interval
307		$first_unknown = false;
308
309		$event_ids = array();
310		$alert_ids = array();
311		while (isset ($events[$event_i]) && $events[$event_i]['utimestamp'] >= $timestamp && $events[$event_i]['utimestamp'] <= ($timestamp + $interval)) {
312			if ($show_events == 1) {
313				$event_value++;
314				$event_ids[] = $events[$event_i]['id_evento'];
315			}
316			if ($show_alerts == 1 && substr ($events[$event_i]['event_type'], 0, 5) == 'alert') {
317				$alert_value++;
318				$alert_ids[] = $events[$event_i]['id_evento'];
319			}
320			if ($show_unknown) {
321				if ($events[$event_i]['event_type'] == 'going_unknown') {
322					if ($is_unknown == false) {
323						$first_unknown = true;
324					}
325					$is_unknown = true;
326				}
327				else if (substr ($events[$event_i]['event_type'], 0, 5) == 'going') {
328					$is_unknown = false;
329				}
330			}
331			$event_i++;
332		}
333
334		// In some cases, can be marked as known because a recovery event
335		// was found in same interval. For this cases first_unknown is
336		// checked too
337		if ($is_unknown || $first_unknown) {
338			$unknown_value++;
339		}
340
341		if (!$flash_chart) {
342			// Set the title and time format
343			if ($period <= SECONDS_6HOURS) {
344				$time_format = 'H:i:s';
345			}
346			elseif ($period < SECONDS_1DAY) {
347				$time_format = 'H:i';
348			}
349			elseif ($period < SECONDS_15DAYS) {
350				$time_format = "M \nd H:i";
351			}
352			elseif ($period < SECONDS_1MONTH) {
353				$time_format = "M \nd H\h";
354			}
355			else {
356				$time_format = "M \nd H\h";
357			}
358		}
359		else {
360			// Set the title and time format
361			if ($period <= SECONDS_6HOURS) {
362				$time_format = 'H:i:s';
363			}
364			elseif ($period < SECONDS_1DAY) {
365				$time_format = 'H:i';
366			}
367			elseif ($period < SECONDS_15DAYS) {
368				$time_format = "M d H:i";
369			}
370			elseif ($period < SECONDS_1MONTH) {
371				$time_format = "M d H\h";
372			}
373			else {
374				$time_format = "M d H\h";
375			}
376		}
377
378		$timestamp_short = date($time_format, $timestamp);
379		$long_index[$timestamp_short] = date(
380			html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp);
381		if (!$projection) {
382			$timestamp = $timestamp_short;
383		}
384
385		// Data
386		if ($show_events) {
387			if (!isset($chart[$timestamp]['event'.$series_suffix])) {
388				$chart[$timestamp]['event'.$series_suffix] = 0;
389			}
390
391			$chart[$timestamp]['event'.$series_suffix] += $event_value;
392			$series_type['event'.$series_suffix] = 'points';
393		}
394		if ($show_alerts) {
395			if (!isset($chart[$timestamp]['alert'.$series_suffix])) {
396				$chart[$timestamp]['alert'.$series_suffix] = 0;
397			}
398
399			$chart[$timestamp]['alert'.$series_suffix] += $alert_value;
400			$series_type['alert'.$series_suffix] = 'points';
401		}
402
403		if ($count > 0) {
404			if ($avg_only) {
405				$chart[$timestamp]['sum'.$series_suffix] = $total;
406			}
407			else {
408				$chart[$timestamp]['max'.$series_suffix] = $interval_max;
409				$chart[$timestamp]['sum'.$series_suffix] = $total;
410				$chart[$timestamp]['min'.$series_suffix] = $interval_min;
411			}
412		// Compressed data
413		}
414		else {
415			if ($uncompressed_module || ($timestamp > time ())) {
416				if ($avg_only) {
417					$chart[$timestamp]['sum'.$series_suffix] = 0;
418				}
419				else {
420					$chart[$timestamp]['max'.$series_suffix] = 0;
421					$chart[$timestamp]['sum'.$series_suffix] = 0;
422					$chart[$timestamp]['min'.$series_suffix] = 0;
423				}
424			}
425			else {
426				if ($avg_only) {
427					$chart[$timestamp]['sum'.$series_suffix] = $last_known;
428				}
429				else {
430					$chart[$timestamp]['max'.$series_suffix] = $last_known;
431					$chart[$timestamp]['sum'.$series_suffix] = $last_known;
432					$chart[$timestamp]['min'.$series_suffix] = $last_known;
433				}
434			}
435		}
436
437		if ($show_unknown) {
438			if (!isset($chart[$timestamp]['unknown'.$series_suffix])) {
439				$chart[$timestamp]['unknown'.$series_suffix] = 0;
440			}
441
442			$chart[$timestamp]['unknown'.$series_suffix] = $unknown_value;
443			$series_type['unknown'.$series_suffix] = 'area';
444		}
445
446		//$chart[$timestamp]['count'] = 0;
447		/////////
448		//$chart[$timestamp]['timestamp_bottom'] = $timestamp;
449		//$chart[$timestamp]['timestamp_top'] = $timestamp + $interval;
450		/////////
451
452		//Baseline was replaced by compare graphs feature
453		/*if ($baseline) {
454			$chart[$timestamp]['baseline'.$series_suffix] = array_shift ($baseline_data);
455			if ($chart[$timestamp]['baseline'.$series_suffix] == NULL) {
456				$chart[$timestamp]['baseline'.$series_suffix] = 0;
457			}
458		}*/
459
460		if (!empty($event_ids)) {
461			$chart_extra_data[count($chart)-1]['events'] = implode(',',$event_ids);
462		}
463		if (!empty($alert_ids)) {
464			$chart_extra_data[count($chart)-1]['alerts'] = implode(',',$alert_ids);
465		}
466	}
467
468
469	if (!is_null($percentil)) {
470		$avg = array_map(function($item) { return $item['sum'];}, $chart);
471
472		$percentil_result = get_percentile($percentil, $avg);
473
474		//Fill the data of chart
475		array_walk($chart, function(&$item) use ($percentil_result, $series_suffix) {
476			$item['percentil' . $series_suffix] = $percentil_result; });
477		$series_type['percentil' . $series_suffix] = 'line';
478	}
479}
480
481
482function grafico_modulo_sparse_data ($agent_module_id, $period, $show_events,
483	$width, $height , $title = '', $unit_name = null,
484	$show_alerts = false, $avg_only = 0, $date = 0, $unit = '',
485	$baseline = 0, $return_data = 0, $show_title = true, $projection = false,
486	$adapt_key = '', $compare = false, $series_suffix = '', $series_suffix_str = '',
487	$show_unknown = false, $percentil = null) {
488
489	global $config;
490	global $chart;
491	global $color;
492	global $legend;
493	global $long_index;
494	global $series_type;
495	global $chart_extra_data;
496	global $warning_min;
497	global $critical_min;
498	global $graphic_type;
499	global $max_value;
500	global $min_value;
501
502
503	$chart = array();
504	$color = array();
505	$legend = array();
506	$long_index = array();
507	$warning_min = 0;
508	$critical_min = 0;
509	$start_unknown = false;
510
511	// Set variables
512	if ($date == 0) $date = get_system_time();
513	$datelimit = $date - $period;
514	$search_in_history_db = db_search_in_history_db($datelimit);
515	$resolution = $config['graph_res'] * 50; //Number of points of the graph
516	$interval = (int) ($period / $resolution);
517	$agent_name = modules_get_agentmodule_agent_name ($agent_module_id);
518	$agent_id = agents_get_agent_id ($agent_name);
519	$module_name = modules_get_agentmodule_name ($agent_module_id);
520	$id_module_type = modules_get_agentmodule_type ($agent_module_id);
521	$module_type = modules_get_moduletype_name ($id_module_type);
522	$uncompressed_module = is_module_uncompressed ($module_type);
523	if ($uncompressed_module) {
524		$avg_only = 1;
525	}
526
527	$flash_chart = $config['flash_charts'];
528
529
530	// Get event data (contains alert data too)
531	$events = array();
532	if ($show_unknown == 1 || $show_events == 1 || $show_alerts == 1) {
533		$events = db_get_all_rows_filter ('tevento',
534			array ('id_agentmodule' => $agent_module_id,
535				"utimestamp > $datelimit",
536				"utimestamp < $date",
537				'order' => 'utimestamp ASC'),
538			array ('id_evento', 'evento', 'utimestamp', 'event_type'));
539
540		// Get the last event after inverval to know if graph start on unknown
541		$prev_event = db_get_row_filter ('tevento',
542			array ('id_agentmodule' => $agent_module_id,
543				"utimestamp <= $datelimit",
544				'order' => 'utimestamp DESC'));
545		if (isset($prev_event['event_type']) && $prev_event['event_type'] == 'going_unknown') {
546			$start_unknown = true;
547		}
548
549		if ($events === false) {
550			$events = array ();
551		}
552	}
553
554	// Get module data
555	$data = db_get_all_rows_filter ('tagente_datos',
556		array ('id_agente_modulo' => (int)$agent_module_id,
557			"utimestamp > $datelimit",
558			"utimestamp < $date",
559			'order' => 'utimestamp ASC'),
560		array ('datos', 'utimestamp'), 'AND', $search_in_history_db);
561
562
563	// Get module warning_min and critical_min
564	$warning_min = db_get_value('min_warning','tagente_modulo','id_agente_modulo',$agent_module_id);
565	$critical_min = db_get_value('min_critical','tagente_modulo','id_agente_modulo',$agent_module_id);
566
567	if ($data === false) {
568		$data = array ();
569	}
570
571
572	if ($uncompressed_module) {
573		// Uncompressed module data
574
575		$min_necessary = 1;
576	}
577	else {
578		// Compressed module data
579
580		// Get previous data
581		$previous_data = modules_get_previous_data ($agent_module_id, $datelimit);
582		if ($previous_data !== false) {
583			$previous_data['utimestamp'] = $datelimit;
584			array_unshift ($data, $previous_data);
585		}
586
587		// Get next data
588		$nextData = modules_get_next_data ($agent_module_id, $date);
589		if ($nextData !== false) {
590			array_push ($data, $nextData);
591		}
592		else if (count ($data) > 0) {
593			// Propagate the last known data to the end of the interval
594			$nextData = array_pop ($data);
595			array_push ($data, $nextData);
596			$nextData['utimestamp'] = $date;
597			array_push ($data, $nextData);
598		}
599
600		$min_necessary = 2;
601	}
602
603	// Check available data
604	if (count ($data) < $min_necessary) {
605		if (!$graphic_type) {
606			if (!$projection) {
607				return fs_error_image ();
608			}
609			else {
610				return fs_error_image ();
611			}
612		}
613		graphic_error ();
614	}
615
616	// Data iterator
617	$data_i = 0;
618
619	// Set initial conditions
620	if ($data[0]['utimestamp'] == $datelimit) {
621		$previous_data = $data[0]['datos'];
622		$data_i++;
623	}
624	else {
625		$previous_data = 0;
626	}
627
628	// Get baseline data
629	$baseline_data = array();
630	if ($baseline) {
631		$baseline_data = array ();
632		if ($baseline == 1) {
633			$baseline_data = enterprise_hook(
634				'reporting_enterprise_get_baseline',
635				array ($agent_module_id, $period, $width, $height , $title, $unit_name, $date));
636			if ($baseline_data === ENTERPRISE_NOT_HOOK) {
637				$baseline_data = array ();
638			}
639		}
640	}
641
642	if (empty($unit)) {
643		$unit = modules_get_unit($agent_module_id);
644	}
645
646	// Calculate chart data
647	grafico_modulo_sparse_data_chart ($chart, $chart_data_extra, $long_index,
648		$data, $data_i, $previous_data, $resolution, $interval, $period, $datelimit,
649		$projection, $avg_only, $uncompressed_module,
650		$show_events, $show_alerts, $show_unknown, $baseline,
651		$baseline_data, $events, $series_suffix, $start_unknown,
652		$percentil);
653
654
655
656	// Return chart data and don't draw
657	if ($return_data == 1) {
658		return $chart;
659	}
660
661	$graph_stats = get_statwin_graph_statistics($chart, $series_suffix);
662
663	// Fix event and alert scale
664	if ($max_value > 0) {
665		$event_max = 2 + (float)$max_value * 1.05;
666	}
667	else {
668		$event_max = abs(($max_value+$min_value)/2);
669		if ($event_max < 5) {
670			$event_max = 5;
671		}
672	}
673
674	foreach ($chart as $timestamp => $chart_data) {
675		if ($show_events && $chart_data['event' . $series_suffix] > 0) {
676			$chart[$timestamp]['event' . $series_suffix] = $event_max * 1.2;
677		}
678		if ($show_alerts && $chart_data['alert' . $series_suffix] > 0) {
679			$chart[$timestamp]['alert' . $series_suffix] = $event_max * 1.10;
680		}
681		if ($show_unknown && $chart_data['unknown' . $series_suffix] > 0) {
682			$chart[$timestamp]['unknown' . $series_suffix] = $event_max * 1.05;
683		}
684	}
685
686	// Only show caption if graph is not small
687	if ($width > MIN_WIDTH_CAPTION && $height > MIN_HEIGHT)
688		//Flash chart
689		$caption =
690			__('Max. Value') . $series_suffix_str . ': ' . $graph_stats['sum']['max'] . '    ' .
691			__('Avg. Value') . $series_suffix_str . ': ' .  $graph_stats['sum']['avg'] . '    ' .
692			__('Min. Value') . $series_suffix_str . ': ' . $graph_stats['sum']['min'] . '    ' .
693			__('Units. Value') . $series_suffix_str . ': ' . $unit;
694	else
695		$caption = array();
696
697	///////
698	// Color commented not to restrict serie colors
699	if ($show_events) {
700		$color['event' . $series_suffix] =
701			array('border' => '#ff0000', 'color' => '#ff0000',
702				'alpha' => CHART_DEFAULT_ALPHA);
703	}
704	if ($show_alerts) {
705		$color['alert' . $series_suffix] =
706			array('border' => '#ff7f00', 'color' => '#ff7f00',
707				'alpha' => CHART_DEFAULT_ALPHA);
708	}
709	if ($show_unknown) {
710		$color['unknown' . $series_suffix] =
711			array('border' => '#999999', 'color' => '#999999',
712				'alpha' => CHART_DEFAULT_ALPHA);
713	}
714	$color['max'.$series_suffix] = array(
715		'border' => '#000000', 'color' => $config['graph_color3'],
716		'alpha' => CHART_DEFAULT_ALPHA);
717	$color['sum'.$series_suffix] = array(
718		'border' => '#000000', 'color' => $config['graph_color2'],
719		'alpha' => CHART_DEFAULT_ALPHA);
720	$color['min'.$series_suffix] = array(
721		'border' => '#000000', 'color' => $config['graph_color1'],
722		'alpha' => CHART_DEFAULT_ALPHA);
723	//Baseline was replaced by compare graph feature
724	//$color['baseline'.$series_suffix] = array('border' => null, 'color' => '#0097BD', 'alpha' => 10);
725	$color['unit'.$series_suffix] = array('border' => null, 'color' => '#0097BC', 'alpha' => 10);
726
727	if ($show_events) {
728		$legend['event'.$series_suffix_str] = __('Events').$series_suffix_str;
729		$chart_extra_data['legend_events'] = $legend['event'].$series_suffix_str;
730	}
731	if ($show_alerts) {
732		$legend['alert'.$series_suffix] = __('Alerts').$series_suffix_str;
733		$chart_extra_data['legend_alerts'] = $legend['alert'.$series_suffix_str];
734	}
735
736	if (!$avg_only) {
737		$legend['max'.$series_suffix] = __('Max').$series_suffix_str.': '.__('Last').': '.rtrim(number_format($graph_stats['max']['last'], 2), '.0').' '.$unit.' ; '.__('Avg').': '.rtrim(number_format($graph_stats['max']['avg'], 2), '.0').' '.$unit.' ; '.__('Max').': '.rtrim(number_format($graph_stats['max']['max'], 2), '.0').' '.$unit.' ; '.__('Min').': '.rtrim(number_format($graph_stats['max']['min'], 2), '.0').' '.$unit.'--> '.__('Selected');
738		$legend['sum'.$series_suffix] = __('Avg').$series_suffix_str.': '.__('Last').': '.rtrim(number_format($graph_stats['sum']['last'], 2), '.0').' '.$unit.' ; '.__('Avg').': '.rtrim(number_format($graph_stats['sum']['avg'], 2), '.0').' '.$unit.' ; '.__('Max').': '.rtrim(number_format($graph_stats['sum']['max'], 2), '.0').' '.$unit.' ; '.__('Min').': '.rtrim(number_format($graph_stats['sum']['min'], 2), '.0').' '.$unit.'--> '.__('Selected');
739		$legend['min'.$series_suffix] = __('Min').$series_suffix_str.': '.__('Last').': '.rtrim(number_format($graph_stats['min']['last'], 2), '.0').' '.$unit.' ; '.__('Avg').': '.rtrim(number_format($graph_stats['min']['avg'], 2), '.0').' '.$unit.' ; '.__('Max').': '.rtrim(number_format($graph_stats['min']['max'], 2), '.0').' '.$unit.' ; '.__('Min').': '.rtrim(number_format($graph_stats['min']['min'], 2), '.0').' '.$unit.'--> '.__('Selected');
740	}
741	else
742		$legend['sum'.$series_suffix] = __('Avg').$series_suffix_str.': '.__('Last').': '.rtrim(number_format($graph_stats['sum']['last'], 2), '.0').' '.$unit.' ; '.__('Avg').': '.rtrim(number_format($graph_stats['sum']['avg'], 2), '.0').' '.$unit.' ; '.__('Max').': '.rtrim(number_format($graph_stats['sum']['max'], 2), '.0').' '.$unit.' ; '.__('Min').': '.rtrim(number_format($graph_stats['sum']['min'], 2), '.0').' '.$unit.'--> '.__('Selected');
743	//Baseline was replaced by compare graph feature
744	/*if ($baseline) {
745		$legend['baseline'.$series_suffix] = __('Baseline');
746	}*/
747
748	if ($show_unknown) {
749		$legend['unknown'.$series_suffix] = __('Unknown').$series_suffix_str;
750		$chart_extra_data['legend_unknown'] = $legend['unknown'.$series_suffix_str];
751	}
752
753	if (!is_null($percentil)) {
754		$first_data = reset($chart);
755		$percentil_value = format_for_graph($first_data['percentil'], 2);
756
757		$legend['percentil'.$series_suffix] = __('Percentile %dº', $percentil)  .$series_suffix_str . " (" . $percentil_value . " " . $unit . ") ";
758		$chart_extra_data['legend_percentil'] = $legend['percentil'.$series_suffix_str];
759	}
760}
761
762function grafico_modulo_sparse ($agent_module_id, $period, $show_events,
763	$width, $height , $title = '', $unit_name = null,
764	$show_alerts = false, $avg_only = 0, $pure = false, $date = 0,
765	$unit = '', $baseline = 0, $return_data = 0, $show_title = true,
766	$only_image = false, $homeurl = '', $ttl = 1, $projection = false,
767	$adapt_key = '', $compare = false, $show_unknown = false,
768	$menu = true, $backgroundColor = 'white', $percentil = null,
769	$dashboard = false, $vconsole = false) {
770
771	global $config;
772	global $graphic_type;
773
774
775	$flash_chart = $config['flash_charts'];
776
777	enterprise_include_once("include/functions_reporting.php");
778
779	global $chart;
780	global $color;
781	global $color_prev;
782	global $legend;
783	global $long_index;
784	global $series_type;
785	global $chart_extra_data;
786	global $warning_min;
787	global $critical_min;
788
789	$series_suffix_str = '';
790	if ($compare !== false) {
791		$series_suffix = '2';
792		$series_suffix_str = ' (' . __('Previous') . ')';
793		// Build the data of the previous period
794
795		grafico_modulo_sparse_data ($agent_module_id, $period,
796			$show_events, $width, $height, $title, $unit_name,
797			$show_alerts, $avg_only, $date-$period, $unit, $baseline,
798			$return_data, $show_title, $projection, $adapt_key,
799			$compare, $series_suffix, $series_suffix_str,
800			$show_unknown, $percentil);
801
802
803
804		switch ($compare) {
805			case 'separated':
806				// Store the chart calculated
807				$chart_prev = $chart;
808				$legend_prev = $legend;
809				$long_index_prev = $long_index;
810				$series_type_prev = $series_type;
811				$color_prev = $color;
812				break;
813			case 'overlapped':
814				// Store the chart calculated deleting index,
815				// because will be over the current period
816				$chart_prev = array_values($chart);
817				$legend_prev = $legend;
818				$series_type_prev = $series_type;
819				$color_prev = $color;
820				foreach($color_prev as $k => $col) {
821					$color_prev[$k]['color'] = '#' .
822						get_complementary_rgb($color_prev[$k]['color']);
823				}
824				break;
825		}
826	}
827
828
829	// Build the data of the current period
830	$data_returned = grafico_modulo_sparse_data ($agent_module_id,
831		$period, $show_events,
832		$width, $height , $title, $unit_name,
833		$show_alerts, $avg_only,
834		$date, $unit, $baseline, $return_data, $show_title,
835		$projection, $adapt_key, $compare, '', '', $show_unknown,
836		$percentil);
837
838
839	if ($return_data) {
840		return $data_returned;
841	}
842
843	if ($compare === 'overlapped') {
844		$i = 0;
845		foreach ($chart as $k=>$v) {
846			if (!isset($chart_prev[$i])) {
847				continue;
848			}
849			$chart[$k] = array_merge($v,$chart_prev[$i]);
850			$i++;
851		}
852
853		$legend = array_merge($legend, $legend_prev);
854		$color = array_merge($color, $color_prev);
855	}
856
857	if ($only_image) {
858		$flash_chart = false;
859	}
860
861	$water_mark = array('file' =>
862		$config['homedir'] . "/images/logo_vertical_water.png",
863		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
864
865	if ($config['type_module_charts'] === 'area') {
866		if ($compare === 'separated') {
867			return
868				area_graph($flash_chart, $chart, $width, $height/2, $color,
869					$legend, $long_index,
870					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
871					$title, $unit, $homeurl, $water_mark, $config['fontpath'],
872					$config['font_size'], $unit, $ttl, $series_type,
873					$chart_extra_data, $warning_min, $critical_min,
874					$adapt_key, false, $series_suffix_str, $menu,
875					$backgroundColor).
876				'<br>'.
877				area_graph($flash_chart, $chart_prev, $width, $height/2,
878					$color_prev, $legend_prev, $long_index_prev,
879					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
880					$title, $unit, $homeurl, $water_mark, $config['fontpath'],
881					$config['font_size'], $unit, $ttl, $series_type_prev,
882					$chart_extra_data, $warning_min, $critical_min,
883					$adapt_key, false, $series_suffix_str, $menu,
884					$backgroundColor);
885		}
886		else {
887			// Color commented not to restrict serie colors
888			return
889				area_graph($flash_chart, $chart, $width, $height, $color,
890					$legend, $long_index,
891					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
892					$title, $unit, $homeurl, $water_mark, $config['fontpath'],
893					$config['font_size'], $unit, $ttl, $series_type,
894					$chart_extra_data, $warning_min, $critical_min,
895					$adapt_key, false, $series_suffix_str, $menu,
896					$backgroundColor, $dashboard, $vconsole, $agent_module_id);
897		}
898	}
899	elseif ($config['type_module_charts'] === 'line') {
900		if ($compare === 'separated') {
901			return
902				line_graph($flash_chart, $chart, $width, $height/2, $color,
903					$legend, $long_index,
904					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
905					"", $unit, $water_mark, $config['fontpath'],
906					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor).
907				'<br>'.
908				line_graph($flash_chart, $chart_prev, $width, $height/2, $color,
909					$legend, $long_index,
910					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
911					"", $unit, $water_mark, $config['fontpath'],
912					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor);
913		}
914		else {
915			// Color commented not to restrict serie colors
916			return
917				line_graph($flash_chart, $chart, $width, $height, $color,
918					$legend, $long_index,
919					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
920					"", $unit, $water_mark, $config['fontpath'],
921					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor);
922		}
923	}
924}
925
926function graph_get_formatted_date($timestamp, $format1, $format2) {
927	global $config;
928
929	if ($config['flash_charts']) {
930		$date = date("$format1 $format2", $timestamp);
931	}
932	else {
933		$date = date($format1, $timestamp);
934		if ($format2 != '') {
935			$date .= "\n".date($format2, $timestamp);
936		}
937	}
938
939	return $date;
940}
941
942/**
943 * Produces a combined/user defined graph
944 *
945 * @param array List of source modules
946 * @param array List of weighs for each module
947 * @param int Period (in seconds)
948 * @param int Width, in pixels
949 * @param int Height, in pixels
950 * @param string Title for graph
951 * @param string Unit name, for render in legend
952 * @param int Show events in graph (set to 1)
953 * @param int Show alerts in graph (set to 1)
954 * @param int Pure mode (without titles) (set to 1)
955 * @param int Date to start of getting info.
956 * @param mixed If is a projection graph this parameter will be module data with prediction data (the projection)
957 * or false in other case.
958 * @param array List of names for the items. Should have the same size as the module list.
959 * @param array List of units for the items. Should have the same size as the module list.
960 * @param bool Show the last value of the item on the list.
961 * @param bool Show the max value of the item on the list.
962 * @param bool Show the min value of the item on the list.
963 * @param bool Show the average value of the item on the list.
964 *
965 * @return Mixed
966 */
967function graphic_combined_module ($module_list, $weight_list, $period,
968	$width, $height, $title, $unit_name, $show_events = 0,
969	$show_alerts = 0, $pure = 0, $stacked = 0, $date = 0,
970	$only_image = false, $homeurl = '', $ttl = 1, $projection = false,
971	$prediction_period = false, $background_color = 'white',
972	$name_list = array(), $unit_list = array(), $show_last = true, $show_max = true,
973	$show_min = true, $show_avg = true, $labels = false, $dashboard = false, $vconsole = false) {
974
975	global $config;
976	global $graphic_type;
977
978	$time_format_2 = '';
979	$temp_range = $period;
980
981	if ($projection != false) {
982		if ($period < $prediction_period)
983			$temp_range = $prediction_period;
984	}
985
986	// Set the title and time format
987	if ($temp_range <= SECONDS_6HOURS) {
988		$time_format = 'H:i:s';
989	}
990	elseif ($temp_range < SECONDS_1DAY) {
991		$time_format = 'H:i';
992	}
993	elseif ($temp_range < SECONDS_15DAYS) {
994		$time_format = 'M d';
995		$time_format_2 = 'H:i';
996		if ($projection != false) {
997			$time_format_2 = 'H\h';
998		}
999	}
1000	elseif ($temp_range <= SECONDS_1MONTH) {
1001		$time_format = 'M d';
1002		$time_format_2 = 'H\h';
1003	}
1004	else {
1005		$time_format = 'M d';
1006		$time_format_2 = 'H\h';
1007	}
1008
1009	// Set variables
1010	if ($date == 0)
1011		$date = get_system_time();
1012	$datelimit = $date - $period;
1013	$search_in_history_db = db_search_in_history_db($datelimit);
1014	$resolution = $config['graph_res'] * 50; //Number of points of the graph
1015	$interval = (int) ($period / $resolution);
1016
1017	// If projection graph, fill with zero previous data to projection interval
1018	if ($projection != false) {
1019		$j = $datelimit;
1020		$in_range = true;
1021		while ($in_range) {
1022			$timestamp_f = graph_get_formatted_date($j, $time_format, $time_format_2);
1023
1024			//$timestamp_f = date('d M Y H:i:s', $j);
1025			$before_projection[$timestamp_f] = 0;
1026
1027			if ($j > $date) {
1028				$in_range = false;
1029			}
1030			$j = $j + $interval;
1031		}
1032	}
1033
1034	// Added support for projection graphs (normal_module + 1(prediction data))
1035	if ($projection !== false) {
1036		$module_number = count ($module_list) + 1;
1037	}
1038	else {
1039		$module_number = count ($module_list);
1040	}
1041
1042	$names_number = count($name_list);
1043	$units_number = count($unit_list);
1044
1045	// interval - This is the number of "rows" we are divided the time to fill data.
1046	//    more interval, more resolution, and slower.
1047	// periodo - Gap of time, in seconds. This is now to (now-periodo) secs
1048
1049	// Init weights
1050	for ($i = 0; $i < $module_number; $i++) {
1051		if (! isset ($weight_list[$i])) {
1052			$weight_list[$i] = 1;
1053		}
1054		else if ($weight_list[$i] == 0) {
1055			$weight_list[$i] = 1;
1056		}
1057	}
1058
1059	// Set data containers
1060	for ($i = 0; $i < $resolution; $i++) {
1061		$timestamp = $datelimit + ($interval * $i);/*
1062		$timestamp_short = date($time_format, $timestamp);
1063		$long_index[$timestamp_short] = date(
1064		html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp);
1065		$timestamp = $timestamp_short;*/
1066
1067		$graph[$timestamp]['count'] = 0;
1068		$graph[$timestamp]['timestamp_bottom'] = $timestamp;
1069		$graph[$timestamp]['timestamp_top'] = $timestamp + $interval;
1070		$graph[$timestamp]['min'] = 0;
1071		$graph[$timestamp]['max'] = 0;
1072		$graph[$timestamp]['event'] = 0;
1073		$graph[$timestamp]['alert'] = 0;
1074	}
1075
1076	$long_index = array();
1077
1078	$graph_values = array();
1079	$module_name_list = array();
1080
1081	// Calculate data for each module
1082	for ($i = 0; $i < $module_number; $i++) {
1083		// If its a projection graph, first module will be data and second will be the projection
1084		if ($projection != false && $i != 0) {
1085			$agent_module_id = $module_list[0];
1086
1087			$id_module_type = modules_get_agentmodule_type ($agent_module_id);
1088			$module_type = modules_get_moduletype_name ($id_module_type);
1089			$uncompressed_module = is_module_uncompressed ($module_type);
1090		}
1091		else {
1092			$agent_module_id = $module_list[$i];
1093
1094			$id_module_type = modules_get_agentmodule_type ($agent_module_id);
1095			$module_type = modules_get_moduletype_name ($id_module_type);
1096			$uncompressed_module = is_module_uncompressed ($module_type);
1097		}
1098
1099		if ($uncompressed_module) {
1100			$avg_only = 1;
1101		}
1102
1103		// Get event data (contains alert data too)
1104		if ($show_events == 1 || $show_alerts == 1) {
1105			$events = db_get_all_rows_filter ('tevento',
1106				array ('id_agentmodule' => $agent_module_id,
1107					"utimestamp > $datelimit",
1108					"utimestamp < $date",
1109					'order' => 'utimestamp ASC'),
1110				array ('evento', 'utimestamp', 'event_type'));
1111			if ($events === false) {
1112				$events = array ();
1113			}
1114		}
1115
1116		// Get module data
1117		$data = db_get_all_rows_filter ('tagente_datos',
1118			array ('id_agente_modulo' => $agent_module_id,
1119				"utimestamp > $datelimit",
1120				"utimestamp < $date",
1121				'order' => 'utimestamp ASC'),
1122			array ('datos', 'utimestamp'), 'AND', $search_in_history_db);
1123		if ($data === false) {
1124			$data = array ();
1125		}
1126
1127		// Uncompressed module data
1128		if ($uncompressed_module) {
1129			$min_necessary = 1;
1130
1131		// Compressed module data
1132		}
1133		else {
1134			// Get previous data
1135			$previous_data = modules_get_previous_data ($agent_module_id, $datelimit);
1136			if ($previous_data !== false) {
1137				$previous_data['utimestamp'] = $datelimit;
1138				array_unshift ($data, $previous_data);
1139			}
1140
1141			// Get next data
1142			$nextData = modules_get_next_data ($agent_module_id, $date);
1143			if ($nextData !== false) {
1144				array_push ($data, $nextData);
1145			}
1146			else if (count ($data) > 0) {
1147				// Propagate the last known data to the end of the interval
1148				$nextData = array_pop ($data);
1149				array_push ($data, $nextData);
1150				$nextData['utimestamp'] = $date;
1151				array_push ($data, $nextData);
1152			}
1153
1154			$min_necessary = 2;
1155		}
1156
1157		// Set initial conditions
1158		$graph_values[$i] = array();
1159
1160		// Check available data
1161		if (count ($data) < $min_necessary) {
1162			continue;
1163		}
1164
1165		if (!empty($name_list) && $names_number == $module_number && isset($name_list[$i])) {
1166			if ($labels[$agent_module_id] != '')
1167				$module_name_list[$i] = $labels[$agent_module_id];
1168			else
1169				$module_name_list[$i] = $agent_name ." / ". $module_name;
1170		}
1171		else {
1172			//Get and process agent name
1173			$agent_name = io_safe_output(
1174				modules_get_agentmodule_agent_name ($agent_module_id));
1175			$agent_name = ui_print_truncate_text($agent_name, 'agent_small', false, true, false, '...', false);
1176
1177			$agent_id = agents_get_agent_id ($agent_name);
1178
1179			//Get and process module name
1180			$module_name = io_safe_output(
1181				modules_get_agentmodule_name ($agent_module_id));
1182			$module_name = sprintf(__("%s"), $module_name);
1183			$module_name = ui_print_truncate_text($module_name, 'module_small', false, true, false, '...', false);
1184
1185			if ($labels[$agent_module_id] != '')
1186				$module_name_list[$i] = $labels[$agent_module_id];
1187			else
1188				$module_name_list[$i] = $agent_name ." / ". $module_name;
1189		}
1190
1191		// Data iterator
1192		$j = 0;
1193
1194		// Event iterator
1195		$k = 0;
1196
1197		// Set initial conditions
1198
1199		//$graph_values[$i] = array();
1200		$temp_graph_values = array();
1201
1202		if ($data[0]['utimestamp'] == $datelimit) {
1203			$previous_data = $data[0]['datos'];
1204			$j++;
1205		}
1206		else {
1207			$previous_data = 0;
1208		}
1209
1210		$max = 0;
1211		$min = null;
1212		$avg = 0;
1213		$countAvg = 0;
1214
1215		// Calculate chart data
1216		$last_known = $previous_data;
1217		for ($l = 0; $l < $resolution; $l++) {
1218			$countAvg ++;
1219
1220			$timestamp = $datelimit + ($interval * $l);
1221			$timestamp_short = graph_get_formatted_date($timestamp, $time_format, $time_format_2);
1222
1223			$long_index[$timestamp_short] = date(
1224			html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp);
1225			//$timestamp = $timestamp_short;
1226
1227			$total = 0;
1228			$count = 0;
1229
1230			// Read data that falls in the current interval
1231			$interval_min = $last_known;
1232			$interval_max = $last_known;
1233			while (isset ($data[$j]) && $data[$j]['utimestamp'] >= $timestamp && $data[$j]['utimestamp'] < ($timestamp + $interval)) {
1234				if ($data[$j]['datos'] > $interval_max) {
1235					$interval_max = $data[$j]['datos'];
1236				}
1237				else if ($data[$j]['datos'] < $interval_max) {
1238					$interval_min = $data[$j]['datos'];
1239				}
1240				$total += $data[$j]['datos'];
1241				$last_known = $data[$j]['datos'];
1242				$count++;
1243				$j++;
1244			}
1245
1246			// Average
1247			if ($count > 0) {
1248				$total /= $count;
1249			}
1250
1251			// Read events and alerts that fall in the current interval
1252			$event_value = 0;
1253			$alert_value = 0;
1254			while (isset ($events[$k]) && $events[$k]['utimestamp'] >= $timestamp && $events[$k]['utimestamp'] <= ($timestamp + $interval)) {
1255				if ($show_events == 1) {
1256					$event_value++;
1257				}
1258				if ($show_alerts == 1 && substr ($events[$k]['event_type'], 0, 5) == 'alert') {
1259					$alert_value++;
1260				}
1261				$k++;
1262			}
1263
1264			// Data
1265			if ($count > 0) {
1266				//$graph_values[$i][$timestamp] = $total * $weight_list[$i];
1267				$temp_graph_values[$timestamp_short] = $total * $weight_list[$i];
1268			}
1269			else {
1270				// Compressed data
1271				if ($uncompressed_module || ($timestamp > time ())) {
1272					$temp_graph_values[$timestamp_short] = 0;
1273				}
1274				else {
1275					$temp_graph_values[$timestamp_short] = $last_known * $weight_list[$i];
1276				}
1277			}
1278
1279			//Extract max, min, avg
1280			if ($max < $temp_graph_values[$timestamp_short]) {
1281				$max = $temp_graph_values[$timestamp_short];
1282			}
1283
1284			if (isset($min)) {
1285				if ($min > $temp_graph_values[$timestamp_short]) {
1286					$min = $temp_graph_values[$timestamp_short];
1287				}
1288			}
1289			else {
1290				$min = $temp_graph_values[$timestamp_short];
1291			}
1292			$avg += $temp_graph_values[$timestamp_short];
1293
1294			// Added to support projection graphs
1295			if ($projection != false and $i != 0) {
1296				$projection_data = array();
1297				$projection_data = array_merge($before_projection, $projection);
1298				$graph_values[$i] = $projection_data;
1299			}
1300			else {
1301				$graph_values[$i] = $temp_graph_values;
1302			}
1303		}
1304
1305		//Add the max, min and avg in the legend
1306		$avg = round($avg / $countAvg, 1);
1307
1308		$graph_stats = get_graph_statistics($graph_values[$i]);
1309
1310		if (!isset($config["short_module_graph_data"]))
1311			$config["short_module_graph_data"] = true;
1312
1313		if ($config["short_module_graph_data"]) {
1314			$min = $graph_stats['min'];
1315			$max = $graph_stats['max'];
1316			$avg = $graph_stats['avg'];
1317			$last = $graph_stats['last'];
1318
1319			if ($min > 1000000)
1320				$min = sprintf("%sM", number_format($min / 1000000, 2));
1321			else if ($min > 1000)
1322				$min = sprintf("%sK", number_format($min / 1000, 2));
1323
1324			if ($max > 1000000)
1325				$max = sprintf("%sM", number_format($max / 1000000, 2));
1326			else if ($max > 1000)
1327				$max = sprintf("%sK", number_format($max / 1000, 2));
1328
1329			if ($avg > 1000000)
1330				$avg = sprintf("%sM", number_format($avg / 1000000, 2));
1331			else if ($avg > 1000)
1332				$avg = sprintf("%sK", number_format($avg / 1000, 2));
1333
1334			if ($last > 1000000)
1335				$last = sprintf("%sM", number_format($last / 1000000, 2));
1336			else if ($last > 1000)
1337				$last = sprintf("%sK", number_format($last / 1000, 2));
1338		}
1339		else {
1340			$min = number_format($graph_stats['min'], 2);
1341			$max = number_format($graph_stats['max'], 2);
1342			$avg = number_format($graph_stats['avg'], 2);
1343			$last = number_format($graph_stats['last'], 2);
1344		}
1345
1346
1347		if (!empty($unit_list) && $units_number == $module_number && isset($unit_list[$i])) {
1348			$unit = $unit_list[$i];
1349		}
1350		else {
1351			$unit = modules_get_unit($agent_module_id);
1352		}
1353
1354		if ($projection == false or ($projection != false and $i == 0)) {
1355			$module_name_list[$i] .= ": ";
1356			if ($show_last)
1357				$module_name_list[$i] .= __('Last') . ": $last $unit; ";
1358			if ($show_max)
1359				$module_name_list[$i] .= __("Max") . ": $max $unit; ";
1360			if ($show_min)
1361				$module_name_list[$i] .= __("Min") . ": $min $unit; ";
1362			if ($show_avg)
1363				$module_name_list[$i] .= __("Avg") . ": $avg $unit";
1364		}
1365
1366		if ($weight_list[$i] != 1) {
1367			//$module_name_list[$i] .= " (x". format_numeric ($weight_list[$i], 1).")";
1368			$module_name_list[$i] .= " (x". format_numeric ($weight_list[$i], 1).")";
1369		}
1370
1371		//$graph_values[$module_name_list[$i]] = $graph_values[$i];
1372		//unset($graph_values[$i]);
1373
1374		//$graph_values[$i] = $graph_values[$i];
1375	}
1376
1377	$temp = array();
1378
1379	switch ($stacked) {
1380		case CUSTOM_GRAPH_BULLET_CHART:
1381			$datelimit = $date - $period;
1382			foreach ($module_list as $module) {
1383				$temp[$module] = modules_get_agentmodule($module);
1384				$temp_data = db_get_value_sql('SELECT datos
1385							FROM tagente_datos
1386							WHERE id_agente_modulo = ' . (int) $module .
1387								' AND utimestamp > ' . (int) $datelimit .
1388								' AND utimestamp < ' . (int) $date) .
1389								" ORDER BY utimestamp DESC";
1390
1391				if ($temp_data) {
1392					if (is_numeric($temp_data))
1393						$value = $temp_data;
1394					else
1395						$value = count($value);
1396				}
1397				else {
1398					$value = false;
1399				}
1400
1401				if ($labels[$module] != '')
1402					$temp[$module]['label'] = $labels[$module];
1403				$temp[$module]['value'] = $value;
1404				$temp[$module]['max'] = reporting_get_agentmodule_data_max($module,$period,$date);
1405				$temp[$module]['min'] = reporting_get_agentmodule_data_min($module,$period,$date);
1406
1407			}
1408
1409			break;
1410		case CUSTOM_GRAPH_HBARS:
1411		case CUSTOM_GRAPH_VBARS:
1412			$datelimit = $date - $period;
1413
1414			$label = '';
1415			foreach ($module_list as $module) {
1416				$module_data = modules_get_agentmodule($module);
1417				$temp_data = db_get_value_sql('SELECT datos
1418							FROM tagente_datos
1419							WHERE id_agente_modulo = ' . (int) $module .
1420								' AND utimestamp > ' . (int) $datelimit .
1421								' AND utimestamp < ' . (int) $date) .
1422								" ORDER BY utimestamp DESC";
1423
1424				$agent_name = io_safe_output(
1425					modules_get_agentmodule_agent_name ($module));
1426
1427				if ($labels[$module] != '')
1428					$label = $labels[$module];
1429				else
1430					$label = $agent_name . " - " .$module_data['nombre'];
1431				$temp[$label]['g'] = round($temp_data,4);
1432
1433			}
1434			break;
1435		case CUSTOM_GRAPH_PIE:
1436			$datelimit = $date - $period;
1437			$total_modules = 0;
1438			foreach ($module_list as $module) {
1439				$data_module = modules_get_agentmodule($module);
1440				$temp_data = db_get_value_sql('SELECT datos
1441							FROM tagente_datos
1442							WHERE id_agente_modulo = ' . (int) $module .
1443								' AND utimestamp > ' . (int) $datelimit .
1444								' AND utimestamp < ' . (int) $date) .
1445								" ORDER BY utimestamp DESC";
1446				if ( $temp_data ){
1447					if (is_numeric($temp_data))
1448						$value = $temp_data;
1449					else
1450						$value = count($value);
1451				}
1452				else {
1453					$value = false;
1454				}
1455				$total_modules += $value;
1456
1457				if ( !isset($labels[$module]) )
1458					$label = $labels[$module];
1459				else
1460					$label = $data_module['nombre'];
1461
1462				$label = io_safe_output($label);
1463				$temp[$label] = array('value'=>$value,
1464										'unit'=>$data_module['unit']);
1465			}
1466			$temp['total_modules'] = $total_modules;
1467			break;
1468		case CUSTOM_GRAPH_GAUGE:
1469			$datelimit = $date - $period;
1470			$i = 0;
1471			foreach ($module_list as $module) {
1472				$temp[$module] = modules_get_agentmodule($module);
1473				$temp_data = db_get_value_sql('SELECT datos
1474							FROM tagente_datos
1475							WHERE id_agente_modulo = ' . (int) $module .
1476								' AND utimestamp > ' . (int) $datelimit .
1477								' AND utimestamp < ' . (int) $date) .
1478								" ORDER BY utimestamp DESC";
1479				if ( $temp_data ) {
1480					if (is_numeric($temp_data))
1481						$value = $temp_data;
1482					else
1483						$value = count($value);
1484				}
1485				else {
1486					$value = false;
1487				}
1488				$temp[$module]['label'] = ($labels[$module] != '') ? $labels[$module] : $temp[$module]['nombre'];
1489
1490				$temp[$module]['value'] = $value;
1491				$temp[$module]['label'] = ui_print_truncate_text($temp[$module]['label'],"module_small",false,true,false,"..");
1492
1493				if ($temp[$module]['unit'] == '%') {
1494					$temp[$module]['min'] =	0;
1495					$temp[$module]['max'] = 100;
1496				}
1497				else {
1498					$min = $temp[$module]['min'];
1499					if ($temp[$module]['max'] == 0)
1500						$max = reporting_get_agentmodule_data_max($module,$period,$date);
1501					else
1502						$max = $temp[$module]['max'];
1503					$temp[$module]['min'] = ($min == 0 ) ? 0 : $min;
1504					$temp[$module]['max'] = ($max == 0 ) ? 100 : $max;
1505				}
1506				$temp[$module]['gauge'] = "gauge_" . $i;
1507				$i++;
1508			}
1509			break;
1510		default:
1511			foreach ($graph_values as $graph_group => $point) {
1512				foreach ($point as $timestamp_point => $point_value) {
1513					$temp[$timestamp_point][$graph_group] = $point_value;
1514				}
1515			}
1516			break;
1517	}
1518
1519	$graph_values = $temp;
1520
1521	/*
1522	for ($i = 0; $i < $module_number; $i++) {
1523		if ($weight_list[$i] != 1) {
1524			$module_name_list[$i] .= " (x". format_numeric ($weight_list[$i], 1).")";
1525		}
1526	}
1527	*/
1528
1529	$flash_charts = $config['flash_charts'];
1530
1531	if ($only_image) {
1532		$flash_charts = false;
1533	}
1534
1535
1536	$water_mark = array(
1537		'file' => $config['homedir'] .  "/images/logo_vertical_water.png",
1538		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
1539
1540
1541	//Work around for fixed the agents name with huge size chars.
1542	$fixed_font_size = $config['font_size'] - 1;
1543
1544	//Set graph color
1545
1546	$color = array();
1547
1548	$color[0] = array('border' => '#000000',
1549		'color' => $config['graph_color1'],
1550		'alpha' => CHART_DEFAULT_ALPHA);
1551	$color[1] = array('border' => '#000000',
1552		'color' => $config['graph_color2'],
1553		'alpha' => CHART_DEFAULT_ALPHA);
1554	$color[2] = array('border' => '#000000',
1555		'color' => $config['graph_color3'],
1556		'alpha' => CHART_DEFAULT_ALPHA);
1557	$color[3] = array('border' => '#000000',
1558		'color' => $config['graph_color4'],
1559		'alpha' => CHART_DEFAULT_ALPHA);
1560	$color[4] = array('border' => '#000000',
1561		'color' => $config['graph_color5'],
1562		'alpha' => CHART_DEFAULT_ALPHA);
1563	$color[5] = array('border' => '#000000',
1564		'color' => $config['graph_color6'],
1565		'alpha' => CHART_DEFAULT_ALPHA);
1566	$color[6] = array('border' => '#000000',
1567		'color' => $config['graph_color7'],
1568		'alpha' => CHART_DEFAULT_ALPHA);
1569	$color[7] = array('border' => '#000000',
1570		'color' => $config['graph_color8'],
1571		'alpha' => CHART_DEFAULT_ALPHA);
1572	$color[8] = array('border' => '#000000',
1573		'color' => $config['graph_color9'],
1574		'alpha' => CHART_DEFAULT_ALPHA);
1575	$color[9] = array('border' => '#000000',
1576		'color' => $config['graph_color10'],
1577		'alpha' => CHART_DEFAULT_ALPHA);
1578	$color[11] = array('border' => '#000000',
1579		'color' => COL_GRAPH9,
1580		'alpha' => CHART_DEFAULT_ALPHA);
1581	$color[12] = array('border' => '#000000',
1582		'color' => COL_GRAPH10,
1583		'alpha' => CHART_DEFAULT_ALPHA);
1584	$color[13] = array('border' => '#000000',
1585		'color' => COL_GRAPH11,
1586		'alpha' => CHART_DEFAULT_ALPHA);
1587	$color[14] = array('border' => '#000000',
1588		'color' => COL_GRAPH12,
1589		'alpha' => CHART_DEFAULT_ALPHA);
1590	$color[15] = array('border' => '#000000',
1591		'color' => COL_GRAPH13,
1592		'alpha' => CHART_DEFAULT_ALPHA);
1593
1594
1595	switch ($stacked) {
1596		case CUSTOM_GRAPH_AREA:
1597			return area_graph($flash_charts, $graph_values, $width,
1598				$height, $color, $module_name_list, $long_index,
1599				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1600				"", "", $homeurl, $water_mark, $config['fontpath'],
1601				$fixed_font_size, $unit, $ttl, array(), array(), 0,  0,  '',
1602				false, '', true, $background_color,$dashboard, $vconsole);
1603			break;
1604		default:
1605		case CUSTOM_GRAPH_STACKED_AREA:
1606			return stacked_area_graph($flash_charts, $graph_values,
1607				$width, $height, $color, $module_name_list, $long_index,
1608				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1609				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1610				"", $ttl, $homeurl, $background_color,$dashboard, $vconsole);
1611			break;
1612		case CUSTOM_GRAPH_LINE:
1613			return line_graph($flash_charts, $graph_values, $width,
1614				$height, $color, $module_name_list, $long_index,
1615				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1616				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1617				$unit, $ttl, $homeurl, $background_color,$dashboard, $vconsole);
1618			break;
1619		case CUSTOM_GRAPH_STACKED_LINE:
1620			return stacked_line_graph($flash_charts, $graph_values,
1621				$width, $height, $color, $module_name_list, $long_index,
1622				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1623				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1624				"", $ttl, $homeurl, $background_color,$dashboard, $vconsole);
1625			break;
1626		case CUSTOM_GRAPH_BULLET_CHART:
1627			return stacked_bullet_chart($flash_charts, $graph_values,
1628				$width, $height, $color, $module_name_list, $long_index,
1629				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1630				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1631				"", $ttl, $homeurl, $background_color);
1632			break;
1633		case CUSTOM_GRAPH_GAUGE:
1634			return stacked_gauge($flash_charts, $graph_values,
1635				$width, $height, $color, $module_name_list, $long_index,
1636				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1637				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1638				"", $ttl, $homeurl, $background_color);
1639			break;
1640		case CUSTOM_GRAPH_HBARS:
1641			return hbar_graph($flash_charts, $graph_values,
1642				$width, $height, $color, $module_name_list, $long_index,
1643				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1644				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1645				"", $ttl, $homeurl, $background_color);
1646			break;
1647		case CUSTOM_GRAPH_VBARS:
1648			return vbar_graph($flash_charts, $graph_values,
1649				$width, $height, $color, $module_name_list, $long_index,
1650				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1651				"", "", $water_mark, $config['fontpath'], $fixed_font_size,
1652				"", $ttl, $homeurl, $background_color);
1653			break;
1654		case CUSTOM_GRAPH_PIE:
1655			return flot_custom_pie_chart($flash_charts, $graph_values,
1656				$width, $height, $color, $module_name_list, $long_index,
1657				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1658				"", "", $water_mark, $config['fontpath'], ($config['font_size']+1),
1659				"", $ttl, $homeurl, $background_color,'other');
1660			break;
1661	}
1662}
1663
1664/**
1665 * Print a graph with access data of agents
1666 *
1667 * @param integer id_agent Agent ID
1668 * @param integer width pie graph width
1669 * @param integer height pie graph height
1670 * @param integer period time period
1671 * @param bool return or echo the result flag
1672 */
1673function graphic_agentaccess ($id_agent, $width, $height, $period = 0, $return = false) {
1674	global $config;
1675	global $graphic_type;
1676
1677
1678	$data = array ();
1679
1680	$resolution = $config["graph_res"] * ($period * 2 / $width); // Number of "slices" we want in graph
1681
1682	$interval = (int) ($period / $resolution);
1683	$date = get_system_time ();
1684	$datelimit = $date - $period;
1685	$periodtime = floor ($period / $interval);
1686	$time = array ();
1687	$data = array ();
1688
1689	$empty_data = true;
1690	for ($i = 0; $i < $interval; $i++) {
1691		$bottom = $datelimit + ($periodtime * $i);
1692		if (! $graphic_type) {
1693			$name = date('G:i', $bottom);
1694		}
1695		else {
1696			$name = $bottom;
1697		}
1698
1699		$top = $datelimit + ($periodtime * ($i + 1));
1700		switch ($config["dbtype"]) {
1701			case "mysql":
1702			case "postgresql":
1703				$data[$name]['data'] = (int) db_get_value_filter ('COUNT(*)',
1704					'tagent_access',
1705					array ('id_agent' => $id_agent,
1706						'utimestamp > '.$bottom,
1707						'utimestamp < '.$top));
1708				break;
1709			case "oracle":
1710				$data[$name]['data'] = (int) db_get_value_filter ('count(*)',
1711					'tagent_access',
1712					array ('id_agent' => $id_agent,
1713						'utimestamp > '.$bottom,
1714						'utimestamp < '.$top));
1715				break;
1716		}
1717
1718		if ($data[$name]['data'] != 0) {
1719			$empty_data = false;
1720		}
1721	}
1722
1723	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
1724		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
1725
1726	if ($empty_data) {
1727		$out = graph_nodata_image($width, $height);
1728	}
1729	else {
1730		$out = area_graph($config['flash_charts'], $data, $width, $height, null, null, null,
1731			ui_get_full_url("images/image_problem.opaque.png", false, false, false),
1732			"", "", ui_get_full_url(false, false, false, false), $water_mark,
1733			$config['fontpath'], $config['font_size'], "", 1, array(), array(), 0, 0, '', false, '', false);
1734	}
1735
1736	if ($return) {
1737		return $out;
1738	}
1739	else {
1740		echo $out;
1741	}
1742}
1743
1744/**
1745 * Print a pie graph with alerts defined/fired data
1746 *
1747 * @param integer Number of defined alerts
1748 * @param integer Number of fired alerts
1749 * @param integer width pie graph width
1750 * @param integer height pie graph height
1751 * @param bool return or echo flag
1752 */
1753function graph_alert_status ($defined_alerts, $fired_alerts, $width = 300, $height = 200, $return = false) {
1754	global $config;
1755
1756	$data = array(__('Not fired alerts') => $defined_alerts - $fired_alerts, __('Fired alerts') => $fired_alerts);
1757	$colors = array(COL_NORMAL, COL_ALERTFIRED);
1758
1759	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
1760			'url' => ui_get_full_url("/images/logo_vertical_water.png"));
1761
1762	$out = pie2d_graph($config['flash_charts'], $data, $width, $height, __("other"),
1763		'', '', $config['fontpath'], $config['font_size'], 1, "hidden", $colors);
1764
1765	if ($return) {
1766		return $out;
1767	}
1768	else {
1769		echo $out;
1770	}
1771}
1772
1773// If any value is negative, truncate it to 0
1774function truncate_negatives(&$element) {
1775	if ($element < 0) {
1776		$element = 0;
1777	}
1778}
1779
1780/**
1781 * Print a pie graph with events data of agent or all agents (if id_agent = false)
1782 *
1783 * @param integer id_agent Agent ID
1784 * @param integer width pie graph width
1785 * @param integer height pie graph height
1786 * @param bool return or echo flag
1787 * @param bool show_not_init flag
1788 */
1789function graph_agent_status ($id_agent = false, $width = 300, $height = 200, $return = false, $show_not_init = false, $data_agents=false) {
1790	global $config;
1791
1792
1793	$filter = array('disabled' => 0, 'id_grupo' => array_keys(users_get_groups(false, 'AR', false)));
1794
1795
1796	if (!empty($id_agent)) {
1797		$filter['id_agente'] = $id_agent;
1798	}
1799
1800	$fields = array('SUM(critical_count) AS Critical',
1801		'SUM(warning_count) AS Warning',
1802		'SUM(normal_count) AS Normal',
1803		'SUM(unknown_count) AS Unknown');
1804
1805	if ($show_not_init) {
1806		$fields[] = 'SUM(notinit_count) "Not init"';
1807	}
1808
1809	if ($data_agents == false) {
1810		$data = db_get_row_filter('tagente', $filter, $fields);
1811	} else {
1812		$data = $data_agents;
1813	}
1814
1815	if (empty($data)) {
1816		$data = array();
1817	}
1818
1819	array_walk($data, 'truncate_negatives');
1820
1821	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
1822		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
1823
1824	//$colors = array(COL_CRITICAL, COL_WARNING, COL_NORMAL, COL_UNKNOWN);
1825	$colors[__('Critical')] = COL_CRITICAL;
1826	$colors[__('Warning')] = COL_WARNING;
1827	$colors[__('Normal')] = COL_NORMAL;
1828	$colors[__('Unknown')] = COL_UNKNOWN;
1829
1830	if ($show_not_init) {
1831		$colors[__('Not init')] = COL_NOTINIT;
1832	}
1833
1834	if (array_sum($data) == 0) {
1835		$data = array();
1836	}
1837
1838	$out = pie2d_graph($config['flash_charts'], $data, $width, $height,
1839		__("other"), ui_get_full_url(false, false, false, false), '',
1840		$config['fontpath'], $config['font_size'], 1, "hidden", $colors);
1841
1842	if ($return) {
1843		return $out;
1844	}
1845	else {
1846		echo $out;
1847	}
1848}
1849
1850
1851/**
1852 * Print a pie graph with events data of agent
1853 *
1854 * @param integer width pie graph width
1855 * @param integer height pie graph height
1856 * @param integer id_agent Agent ID
1857 */
1858function graph_event_module ($width = 300, $height = 200, $id_agent) {
1859	global $config;
1860	global $graphic_type;
1861
1862	// Fix: tag filters implemented! for tag functionality groups have to be all user_groups (propagate ACL funct!)
1863	$groups = users_get_groups($config["id_user"]);
1864	$tags_condition = tags_get_acl_tags($config['id_user'], array_keys($groups), 'ER', 'event_condition', 'AND');
1865
1866	$data = array ();
1867	$max_items = 6;
1868	switch ($config["dbtype"]) {
1869		case "mysql":
1870		case "postgresql":
1871			$sql = sprintf ('SELECT COUNT(id_evento) AS count_number,
1872					id_agentmodule
1873				FROM tevento
1874				WHERE tevento.id_agente = %d %s
1875				GROUP BY id_agentmodule ORDER BY count_number DESC LIMIT %d', $id_agent, $tags_condition, $max_items);
1876			break;
1877		case "oracle":
1878			$sql = sprintf ('SELECT COUNT(id_evento) AS count_number,
1879					id_agentmodule
1880				FROM tevento
1881				WHERE tevento.id_agente = %d AND rownum <= %d
1882				GROUP BY id_agentmodule ORDER BY count_number DESC', $id_agent, $max_items);
1883			break;
1884	}
1885
1886	$events = db_get_all_rows_sql ($sql);
1887	if ($events === false) {
1888		if (! $graphic_type) {
1889			return fs_error_image ();
1890		}
1891		graphic_error ();
1892		return;
1893	}
1894
1895	foreach ($events as $event) {
1896		if ($event['id_agentmodule'] == 0) {
1897			$key = __('System') . ' ('.$event['count_number'].')';
1898		}
1899		else {
1900			$key = modules_get_agentmodule_name ($event['id_agentmodule']) .
1901				' ('.$event['count_number'].')';
1902		}
1903
1904		$data[$key] = $event["count_number"];
1905	}
1906
1907	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
1908		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
1909
1910	return pie3d_graph($config['flash_charts'], $data, $width, $height, __("other"),
1911		'', $water_mark, $config['fontpath'], $config['font_size'], 1, "bottom");
1912}
1913
1914function progress_bar($progress, $width, $height, $title = '', $mode = 1, $value_text = false, $color = false, $options = false) {
1915	global $config;
1916
1917	$out_of_lim_str = io_safe_output(__("Out of limits"));
1918
1919	$title = "";
1920
1921	if ($value_text === false) {
1922		$value_text = $progress . "%";
1923	}
1924
1925	$colorRGB = '';
1926	if ($color !== false) {
1927		$colorRGB = html_html2rgb($color);
1928		$colorRGB = implode('|', $colorRGB);
1929	}
1930
1931	$class_tag = '';
1932	$id_tag = '';
1933	if ($options !== false) {
1934		foreach ($options as $option_type => $option_value) {
1935			if ($option_type == 'class')
1936				$class_tag = ' class="' . $option_value . '" ';
1937			else if ($option_type == 'id')
1938				$id_tag = ' id="' . $option_value . '" ';
1939		}
1940	}
1941
1942	require_once("include_graph_dependencies.php");
1943	include_graphs_dependencies($config['homedir'].'/');
1944
1945	$src = ui_get_full_url(
1946		"/include/graphs/fgraph.php?homeurl=../../&graph_type=progressbar" .
1947		"&width=".$width."&height=".$height."&progress=".$progress.
1948		"&mode=" . $mode . "&out_of_lim_str=".$out_of_lim_str .
1949		"&title=".$title."&font=".$config['fontpath']."&value_text=". $value_text .
1950		"&colorRGB=". $colorRGB, false, false, false
1951		);
1952
1953	return "<img title='" . $title . "' alt='" . $title . "'" . $class_tag . $id_tag .
1954		" src='" . $src . "' />";
1955}
1956
1957function progress_bubble($progress, $width, $height, $title = '', $mode = 1, $value_text = false, $color = false) {
1958	global $config;
1959
1960	$hack_metaconsole = '';
1961	if (defined('METACONSOLE'))
1962		$hack_metaconsole = '../../';
1963
1964	$out_of_lim_str = io_safe_output(__("Out of limits"));
1965	$title = "";
1966
1967	if ($value_text === false) {
1968		$value_text = $progress . "%";
1969	}
1970
1971	$colorRGB = '';
1972	if ($color !== false) {
1973		$colorRGB = html_html2rgb($color);
1974		$colorRGB = implode('|', $colorRGB);
1975	}
1976
1977	require_once("include_graph_dependencies.php");
1978	include_graphs_dependencies($config['homedir'].'/');
1979
1980	return "<img title='" . $title . "' alt='" . $title . "'" .
1981		" src='" . $config['homeurl'] . $hack_metaconsole . "/include/graphs/fgraph.php?homeurl=../../&graph_type=progressbubble" .
1982		"&width=".$width."&height=".$height."&progress=".$progress.
1983		"&mode=" . $mode . "&out_of_lim_str=".$out_of_lim_str .
1984		"&title=".$title."&font=".$config['fontpath']."&value_text=". $value_text .
1985		"&colorRGB=". $colorRGB . "' />";
1986}
1987
1988function graph_sla_slicebar ($id, $period, $sla_min, $sla_max, $date, $daysWeek = null, $time_from = null, $time_to = null, $width, $height, $home_url, $ttl = 1, $data = false, $round_corner = null) {
1989	global $config;
1990
1991	if ($round_corner === null) {
1992		$round_corner = $config['round_corner'];
1993	}
1994
1995	// If the data is not provided, we got it
1996	if ($data === false) {
1997		$data = reporting_get_agentmodule_sla_array ($id, $period,
1998			$sla_min, $sla_max, $date, $daysWeek, null, null);
1999	}
2000
2001	$col_planned_downtime = '#20973F';
2002
2003	$colors = array(1 => COL_NORMAL,
2004		2 => COL_WARNING,
2005		3 => COL_CRITICAL,
2006		4 => COL_UNKNOWN,
2007		5 => $col_planned_downtime);
2008
2009	return slicesbar_graph($data, $period, $width, $height, $colors,
2010		$config['fontpath'], $round_corner, $home_url, $ttl);
2011}
2012
2013/**
2014 * Print a pie graph with purge data of agent
2015 *
2016 * @param integer id_agent ID of agent to show
2017 * @param integer width pie graph width
2018 * @param integer height pie graph height
2019 */
2020function grafico_db_agentes_purge ($id_agent, $width = 380, $height = 300) {
2021	global $config;
2022	global $graphic_type;
2023
2024	$filter = array();
2025
2026	if ($id_agent < 1) {
2027		$query = "";
2028	}
2029	else {
2030		$modules = agents_get_modules($id_agent);
2031		$module_ids = array_keys($modules);
2032
2033		if (!empty($module_ids))
2034			$filter['id_agente_modulo'] = $module_ids;
2035	}
2036
2037	// All data (now)
2038	$time_now = time();
2039
2040	// 1 day ago
2041	$time_1day = $time_now - SECONDS_1DAY;
2042
2043	// 1 week ago
2044	$time_1week = $time_now - SECONDS_1WEEK;
2045
2046	// 1 month ago
2047	$time_1month = $time_now - SECONDS_1MONTH;
2048
2049	// Three months ago
2050	$time_3months = $time_now - SECONDS_3MONTHS;
2051
2052	$query_error = false;
2053
2054	// Data from 1 day ago
2055	$num_1day = 0;
2056	$num_1day += (int) db_get_sql('SELECT COUNT(*)
2057										FROM tagente_datos
2058										WHERE utimestamp > ' . $time_1day);
2059	$num_1day += (int) db_get_sql('SELECT COUNT(*)
2060										FROM tagente_datos_string
2061										WHERE utimestamp > ' . $time_1day);
2062	$num_1day += (int) db_get_sql('SELECT COUNT(*)
2063										FROM tagente_datos_log4x
2064										WHERE utimestamp > ' . $time_1day);
2065	if ($num_1day >= 0) {
2066		// Data from 1 week ago
2067		$num_1week = 0;
2068		$num_1week += (int) db_get_sql('SELECT COUNT(*)
2069											FROM tagente_datos
2070											WHERE utimestamp > ' . $time_1week . '
2071											AND utimestamp < ' . $time_1day);
2072		$num_1week += (int) db_get_sql('SELECT COUNT(*)
2073											FROM tagente_datos_string
2074											WHERE utimestamp > ' . $time_1week . '
2075											AND utimestamp < ' . $time_1day);
2076		$num_1week += (int) db_get_sql('SELECT COUNT(*)
2077											FROM tagente_datos_log4x
2078											WHERE utimestamp > ' . $time_1week . '
2079											AND utimestamp < ' . $time_1day);
2080		if ($num_1week >= 0) {
2081			if ($num_1week > 0) {
2082				$num_1week = 0;
2083				$num_1week += (int) db_get_sql('SELECT COUNT(*)
2084													FROM tagente_datos
2085													WHERE utimestamp > ' . $time_1week);
2086				$num_1week += (int) db_get_sql('SELECT COUNT(*)
2087													FROM tagente_datos_string
2088													WHERE utimestamp > ' . $time_1week);
2089				$num_1week += (int) db_get_sql('SELECT COUNT(*)
2090													FROM tagente_datos_log4x
2091													WHERE utimestamp > ' . $time_1week);
2092			}
2093			// Data from 1 month ago
2094			$num_1month = 0;
2095			$num_1month += (int) db_get_sql('SELECT COUNT(*)
2096												FROM tagente_datos
2097												WHERE utimestamp > ' . $time_1month . '
2098												AND utimestamp < ' . $time_1week);
2099			$num_1month += (int) db_get_sql('SELECT COUNT(*)
2100												FROM tagente_datos_string
2101												WHERE utimestamp > ' . $time_1month . '
2102												AND utimestamp < ' . $time_1week);
2103			$num_1month += (int) db_get_sql('SELECT COUNT(*)
2104												FROM tagente_datos_log4x
2105												WHERE utimestamp > ' . $time_1month . '
2106												AND utimestamp < ' . $time_1week);
2107			if ($num_1month >= 0) {
2108				if ($num_1month > 0) {
2109					$num_1month = 0;
2110					$num_1month += (int) db_get_sql('SELECT COUNT(*)
2111														FROM tagente_datos
2112														WHERE utimestamp > ' . $time_1month);
2113					$num_1month += (int) db_get_sql('SELECT COUNT(*)
2114														FROM tagente_datos_string
2115														WHERE utimestamp > ' . $time_1month);
2116					$num_1month += (int) db_get_sql('SELECT COUNT(*)
2117														FROM tagente_datos_log4x
2118														WHERE utimestamp > ' . $time_1month);
2119				}
2120				// Data from 3 months ago
2121				$num_3months = 0;
2122				$num_3months += (int) db_get_sql('SELECT COUNT(*)
2123													FROM tagente_datos
2124													WHERE utimestamp > ' . $time_3months . '
2125													AND utimestamp < ' . $time_1month);
2126				$num_3months += (int) db_get_sql('SELECT COUNT(*)
2127													FROM tagente_datos
2128													WHERE utimestamp > ' . $time_3months . '
2129													AND utimestamp < ' . $time_1month);
2130				$num_3months += (int) db_get_sql('SELECT COUNT(*)
2131													FROM tagente_datos
2132													WHERE utimestamp > ' . $time_3months . '
2133													AND utimestamp < ' . $time_1month);
2134				if ($num_3months >= 0) {
2135					if ($num_3months > 0) {
2136						$num_3months = 0;
2137						$num_3months += (int) db_get_sql('SELECT COUNT(*)
2138															FROM tagente_datos
2139															WHERE utimestamp > ' . $time_3months);
2140						$num_3months += (int) db_get_sql('SELECT COUNT(*)
2141															FROM tagente_datos
2142															WHERE utimestamp > ' . $time_3months);
2143						$num_3months += (int) db_get_sql('SELECT COUNT(*)
2144															FROM tagente_datos
2145															WHERE utimestamp > ' . $time_3months);
2146					}
2147					// All data
2148					$num_all = 0;
2149					$num_all += (int) db_get_sql('SELECT COUNT(*)
2150														FROM tagente_datos
2151														WHERE utimestamp < ' . $time_3months);
2152					$num_all += (int) db_get_sql('SELECT COUNT(*)
2153														FROM tagente_datos
2154														WHERE utimestamp < ' . $time_3months);
2155					$num_all += (int) db_get_sql('SELECT COUNT(*)
2156														FROM tagente_datos
2157														WHERE utimestamp < ' . $time_3months);
2158					if ($num_all >= 0) {
2159						$num_older = $num_all - $num_3months;
2160						if ($config['history_db_enabled'] == 1) {
2161							// All data in common and history database
2162							$num_all_w_history = 0;
2163							$num_all_w_history += (int) db_get_sql('SELECT COUNT(*)
2164																FROM tagente_datos
2165																WHERE utimestamp < ' . $time_3months);
2166							$num_all_w_history += (int) db_get_sql('SELECT COUNT(*)
2167																FROM tagente_datos
2168																WHERE utimestamp < ' . $time_3months);
2169							$num_all_w_history += (int) db_get_sql('SELECT COUNT(*)
2170																FROM tagente_datos
2171																WHERE utimestamp < ' . $time_3months);
2172							if ($num_all_w_history >= 0) {
2173								$num_history = $num_all_w_history - $num_all;
2174							}
2175						}
2176					}
2177				}
2178			}
2179		}
2180	}
2181	else if (($num_1day == 0) && ($num_1week == 0) && ($num_1month == 0) && ($num_3months == 0) && ($num_all == 0)) {
2182		//If no data, returns empty
2183		$query_error = true;
2184	}
2185
2186	// Error
2187	if ($query_error || $num_older < 0 || ($config['history_db_enabled'] == 1 && $num_history < 0)
2188			|| (empty($num_1day) && empty($num_1week) && empty($num_1month)
2189				&& empty($num_3months) && empty($num_all)
2190				&& ($config['history_db_enabled'] == 1 && empty($num_all_w_history)))) {
2191		return html_print_image('images/image_problem.png', true);
2192	}
2193
2194	// Data indexes
2195	$str_1day = __("Today");
2196	$str_1week = "1 ".__("Week");
2197	$str_1month = "1 ".__("Month");
2198	$str_3months = "3 ".__("Months");
2199	$str_older = "> 3 ".__("Months");
2200
2201	// Filling the data array
2202	$data = array();
2203	if (!empty($num_1day))
2204		$data[$str_1day] = $num_1day;
2205	if (!empty($num_1week))
2206		$data[$str_1week] = $num_1week;
2207	if (!empty($num_1month))
2208		$data[$str_1month] = $num_1month;
2209	if (!empty($num_3months))
2210		$data[$str_3months] = $num_3months;
2211	if (!empty($num_older))
2212		$data[$str_older] = $num_older;
2213	if ($config['history_db_enabled'] == 1 && !empty($num_history)) {
2214		// In this pie chart only 5 elements are shown, so we need to remove
2215		// an element. With a history db enabled the >3 months element are dispensable
2216		if (count($data) >= 5 && isset($data[$str_3months]))
2217			unset($data[$str_3months]);
2218
2219		$time_historic_db = time() - ((int)$config['history_db_days'] * SECONDS_1DAY);
2220		$date_human = human_time_comparation($time_historic_db);
2221		$str_history = "> $date_human (".__("History db").")";
2222		$data[$str_history] = $num_history;
2223	}
2224
2225	$water_mark = array(
2226			'file' => $config['homedir'] . "/images/logo_vertical_water.png",
2227			'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false)
2228		);
2229
2230	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2231		__('Other'), '', $water_mark, $config['fontpath'], $config['font_size']);
2232}
2233
2234/**
2235 * Print a horizontal bar graph with packets data of agents
2236 *
2237 * @param integer width pie graph width
2238 * @param integer height pie graph height
2239 */
2240function grafico_db_agentes_paquetes($width = 380, $height = 300) {
2241	global $config;
2242	global $graphic_type;
2243
2244
2245	$data = array ();
2246	$legend = array ();
2247
2248	$agents = agents_get_group_agents (array_keys (users_get_groups (false, 'RR')), false, "none");
2249	$count = agents_get_modules_data_count (array_keys ($agents));
2250	unset ($count["total"]);
2251	arsort ($count, SORT_NUMERIC);
2252	$count = array_slice ($count, 0, 8, true);
2253
2254	foreach ($count as $agent_id => $value) {
2255		$data[$agents[$agent_id]]['g'] = $value;
2256	}
2257
2258	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2259		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2260
2261	return hbar_graph($config['flash_charts'], $data, $width, $height, array(),
2262		$legend, "", "", true, "", $water_mark,
2263		$config['fontpath'], $config['font_size'], false);
2264}
2265
2266/**
2267 * Print a horizontal bar graph with modules data of agents
2268 *
2269 * @param integer height graph height
2270 * @param integer width graph width
2271 */
2272function graph_db_agentes_modulos($width, $height) {
2273	global $config;
2274	global $graphic_type;
2275
2276
2277	$data = array ();
2278
2279	switch ($config['dbtype']) {
2280		case "mysql":
2281		case "postgresql":
2282			$modules = db_get_all_rows_sql ('
2283				SELECT COUNT(id_agente_modulo), id_agente
2284				FROM tagente_modulo
2285				WHERE delete_pending = 0
2286				GROUP BY id_agente
2287				ORDER BY 1 DESC LIMIT 10');
2288			break;
2289		case "oracle":
2290			$modules = db_get_all_rows_sql ('
2291				SELECT COUNT(id_agente_modulo), id_agente
2292				FROM tagente_modulo
2293				WHERE rownum <= 10
2294				AND delete_pending = 0
2295				GROUP BY id_agente
2296				ORDER BY 1 DESC');
2297			break;
2298	}
2299	if ($modules === false)
2300		$modules = array ();
2301
2302	$data = array();
2303	foreach ($modules as $module) {
2304		$agent_name = agents_get_name ($module['id_agente'], "none");
2305
2306		if (empty($agent_name)) {
2307			continue;
2308		}
2309		switch ($config['dbtype']) {
2310			case "mysql":
2311			case "postgresql":
2312				$data[$agent_name]['g'] = $module['COUNT(id_agente_modulo)'];
2313				break;
2314			case "oracle":
2315				$data[$agent_name]['g'] = $module['count(id_agente_modulo)'];
2316				break;
2317		}
2318	}
2319
2320	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2321		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2322
2323	return hbar_graph($config['flash_charts'],
2324		$data, $width, $height, array(),
2325		array(), "", "", true, "",
2326		$water_mark,
2327		$config['fontpath'], $config['font_size'], false);
2328}
2329
2330/**
2331 * Print a pie graph with users activity in a period of time
2332 *
2333 * @param integer width pie graph width
2334 * @param integer height pie graph height
2335 * @param integer period time period
2336 */
2337function graphic_user_activity ($width = 350, $height = 230) {
2338	global $config;
2339	global $graphic_type;
2340
2341	$data = array ();
2342	$max_items = 5;
2343	switch ($config['dbtype']) {
2344		case "mysql":
2345		case "postgresql":
2346			$sql = sprintf ('SELECT COUNT(id_usuario) n_incidents, id_usuario
2347				FROM tsesion
2348				GROUP BY id_usuario
2349				ORDER BY 1 DESC LIMIT %d', $max_items);
2350			break;
2351		case "oracle":
2352			$sql = sprintf ('SELECT COUNT(id_usuario) n_incidents, id_usuario
2353				FROM tsesion
2354				WHERE rownum <= %d
2355				GROUP BY id_usuario
2356				ORDER BY 1 DESC', $max_items);
2357			break;
2358	}
2359	$logins = db_get_all_rows_sql ($sql);
2360
2361	if ($logins == false) {
2362		$logins = array();
2363	}
2364	foreach ($logins as $login) {
2365		$data[$login['id_usuario']] = $login['n_incidents'];
2366	}
2367
2368	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2369		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2370
2371	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2372		__('Other'), '', $water_mark,
2373		$config['fontpath'], $config['font_size']);
2374}
2375
2376/**
2377 * Print a pie graph with priodity incident
2378 */
2379function grafico_incidente_prioridad () {
2380	global $config;
2381	global $graphic_type;
2382
2383	$data_tmp = array (0, 0, 0, 0, 0, 0);
2384	$sql = 'SELECT COUNT(id_incidencia) n_incidents, prioridad
2385		FROM tincidencia
2386		GROUP BY prioridad
2387		ORDER BY 2 DESC';
2388	$incidents = db_get_all_rows_sql ($sql);
2389
2390	if ($incidents == false) {
2391		$incidents = array();
2392	}
2393	foreach ($incidents as $incident) {
2394		if ($incident['prioridad'] < 5)
2395			$data_tmp[$incident['prioridad']] = $incident['n_incidents'];
2396		else
2397			$data_tmp[5] += $incident['n_incidents'];
2398	}
2399	$data = array (__('Informative') => $data_tmp[0],
2400		__('Low') => $data_tmp[1],
2401		__('Medium') => $data_tmp[2],
2402		__('Serious') => $data_tmp[3],
2403		__('Very serious') => $data_tmp[4],
2404		__('Maintenance') => $data_tmp[5]);
2405
2406	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2407		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2408
2409	return pie3d_graph($config['flash_charts'], $data, 320, 200,
2410		__('Other'), '', $water_mark,
2411		$config['fontpath'], $config['font_size']);
2412}
2413
2414/**
2415 * Print a pie graph with incidents data
2416 */
2417function graph_incidents_status () {
2418	global $config;
2419	global $graphic_type;
2420	$data = array (0, 0, 0, 0);
2421
2422	$data = array ();
2423	$data[__('Open incident')] = 0;
2424	$data[__('Closed incident')] = 0;
2425	$data[__('Outdated')] = 0;
2426	$data[__('Invalid')] = 0;
2427
2428	$incidents = db_get_all_rows_filter ('tincidencia',
2429		array ('estado' => array (0, 2, 3, 13)),
2430		array ('estado'));
2431	if ($incidents === false)
2432		$incidents = array ();
2433	foreach ($incidents as $incident) {
2434		if ($incident["estado"] == 0)
2435			$data[__("Open incident")]++;
2436		if ($incident["estado"] == 2)
2437			$data[__("Closed incident")]++;
2438		if ($incident["estado"] == 3)
2439			$data[__("Outdated")]++;
2440		if ($incident["estado"] == 13)
2441			$data[__("Invalid")]++;
2442	}
2443
2444	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2445		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2446
2447	return pie3d_graph($config['flash_charts'], $data, 370, 180,
2448		__('Other'), '', $water_mark,
2449		$config['fontpath'], $config['font_size']);
2450}
2451
2452/**
2453 * Print a pie graph with incident data by group
2454 */
2455function graphic_incident_group () {
2456	global $config;
2457	global $graphic_type;
2458
2459	$data = array ();
2460	$max_items = 5;
2461	switch ($config["dbtype"]) {
2462		case 'mysql':
2463			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incidents, nombre
2464				FROM tincidencia,tgrupo
2465				WHERE tgrupo.id_grupo = tincidencia.id_grupo
2466				GROUP BY tgrupo.id_grupo, nombre ORDER BY 1 DESC LIMIT %d',
2467				$max_items);
2468			break;
2469		case 'oracle':
2470			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incidents, nombre
2471				FROM tincidencia,tgrupo
2472				WHERE tgrupo.id_grupo = tincidencia.id_grupo
2473				AND rownum <= %d
2474				GROUP BY tgrupo.id_grupo, nombre ORDER BY 1 DESC',
2475				$max_items);
2476			break;
2477	}
2478	$incidents = db_get_all_rows_sql ($sql);
2479
2480	$sql = sprintf ('SELECT COUNT(id_incidencia) n_incidents
2481		FROM tincidencia
2482		WHERE tincidencia.id_grupo = 0');
2483
2484	$incidents_all = db_get_value_sql($sql);
2485
2486	if ($incidents == false) {
2487		$incidents = array();
2488	}
2489	foreach ($incidents as $incident) {
2490		$data[$incident['nombre']] = $incident['n_incidents'];
2491	}
2492
2493	if ($incidents_all > 0) {
2494		$data[__('All')] = $incidents_all;
2495	}
2496
2497	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2498		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2499
2500	return pie3d_graph($config['flash_charts'], $data, 320, 200,
2501		__('Other'), '', $water_mark,
2502		$config['fontpath'], $config['font_size']);
2503}
2504
2505/**
2506 * Print a graph with access data of agents
2507 *
2508 * @param integer id_agent Agent ID
2509 * @param integer width pie graph width
2510 * @param integer height pie graph height
2511 * @param integer period time period
2512 */
2513function graphic_incident_user () {
2514	global $config;
2515	global $graphic_type;
2516
2517	$data = array ();
2518	$max_items = 5;
2519	switch ($config["dbtype"]) {
2520		case 'mysql':
2521			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incidents, id_usuario
2522				FROM tincidencia
2523				GROUP BY id_usuario
2524				ORDER BY 1 DESC LIMIT %d', $max_items);
2525			break;
2526		case 'oracle':
2527			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incidents, id_usuario
2528				FROM tincidencia
2529				WHERE rownum <= %d
2530				GROUP BY id_usuario
2531				ORDER BY 1 DESC', $max_items);
2532			break;
2533	}
2534	$incidents = db_get_all_rows_sql ($sql);
2535
2536	if ($incidents == false) {
2537		$incidents = array();
2538	}
2539	foreach ($incidents as $incident) {
2540		if ($incident['id_usuario'] == false) {
2541			$name = __('System');
2542		}
2543		else {
2544			$name = $incident['id_usuario'];
2545		}
2546
2547		$data[$name] = $incident['n_incidents'];
2548	}
2549
2550	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2551		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2552
2553	return pie3d_graph($config['flash_charts'], $data, 320, 200,
2554		__('Other'), '', $water_mark,
2555		$config['fontpath'], $config['font_size']);
2556}
2557
2558/**
2559 * Print a pie graph with access data of incidents source
2560 *
2561 * @param integer width pie graph width
2562 * @param integer height pie graph height
2563 */
2564function graphic_incident_source($width = 320, $height = 200) {
2565	global $config;
2566	global $graphic_type;
2567
2568	$data = array ();
2569	$max_items = 5;
2570
2571	switch ($config["dbtype"]) {
2572		case "mysql":
2573			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incident, origen
2574				FROM tincidencia
2575				GROUP BY `origen`
2576				ORDER BY 1 DESC LIMIT %d', $max_items);
2577			break;
2578		case "postgresql":
2579			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incident, origen
2580				FROM tincidencia
2581				GROUP BY "origen"
2582				ORDER BY 1 DESC LIMIT %d', $max_items);
2583			break;
2584		case "oracle":
2585			$sql = sprintf ('SELECT COUNT(id_incidencia) n_incident, origen
2586				FROM tincidencia
2587				WHERE rownum <= %d
2588				GROUP BY origen
2589				ORDER BY 1 DESC', $max_items);
2590			break;
2591	}
2592	$origins = db_get_all_rows_sql ($sql);
2593
2594	if ($origins == false) {
2595		$origins = array();
2596	}
2597	foreach ($origins as $origin) {
2598		$data[$origin['origen']] = $origin['n_incident'];
2599	}
2600
2601	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2602		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2603
2604	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2605		__('Other'), '', $water_mark,
2606		$config['fontpath'], $config['font_size']);
2607}
2608
2609function graph_events_validated($width = 300, $height = 200, $url = "", $meta = false, $history = false) {
2610	global $config;
2611	global $graphic_type;
2612
2613	$data_graph = reporting_get_count_events_validated(
2614		array('id_group' => array_keys(users_get_groups())));
2615
2616	$colors = array();
2617	foreach ($data_graph as $k => $v) {
2618		if ($k == __('Validated')) {
2619			$colors[$k] = COL_NORMAL;
2620		}
2621		else {
2622			$colors[$k] = COL_CRITICAL;
2623		}
2624	}
2625
2626	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2627		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2628
2629	echo pie3d_graph(
2630		true, $data_graph, $width, $height, __("other"), "",
2631		$water_mark,
2632		$config['fontpath'], $config['font_size'], 1, false, $colors);
2633}
2634
2635/**
2636 * Print a pie graph with events data of group
2637 *
2638 * @param integer width pie graph width
2639 * @param integer height pie graph height
2640 * @param string url
2641 * @param bool if the graph required is or not for metaconsole
2642 * @param bool if the graph required is or not for history table
2643 */
2644function grafico_eventos_grupo ($width = 300, $height = 200, $url = "", $meta = false, $history = false, $noWaterMark = true) {
2645	global $config;
2646	global $graphic_type;
2647
2648	//It was urlencoded, so we urldecode it
2649	$url = html_entity_decode (rawurldecode ($url), ENT_QUOTES);
2650	$data = array ();
2651	$loop = 0;
2652	define ('NUM_PIECES_PIE', 6);
2653
2654
2655	//Hotfix for the id_agente_modulo
2656	$url = str_replace(
2657		'SELECT id_agente_modulo', 'SELECT_id_agente_modulo', $url);
2658
2659
2660	$badstrings = array (";",
2661		"SELECT ",
2662		"DELETE ",
2663		"UPDATE ",
2664		"INSERT ",
2665		"EXEC");
2666	//remove bad strings from the query so queries like ; DELETE FROM  don't pass
2667	$url = str_ireplace ($badstrings, "", $url);
2668
2669
2670	//Hotfix for the id_agente_modulo
2671	$url = str_replace(
2672		'SELECT_id_agente_modulo', 'SELECT id_agente_modulo', $url);
2673
2674
2675	// Choose the table where search if metaconsole or not
2676	if ($meta) {
2677		if ($history) {
2678			$event_table = 'tmetaconsole_event_history';
2679		}
2680		else {
2681			$event_table = 'tmetaconsole_event';
2682		}
2683		$field_extra = ', agent_name';
2684		$groupby_extra = ', server_id';
2685	}
2686	else {
2687		$event_table = 'tevento';
2688		$field_extra = '';
2689		$groupby_extra = '';
2690	}
2691
2692	// Add tags condition to filter
2693	$tags_condition = tags_get_acl_tags($config['id_user'], 0, 'ER', 'event_condition', 'AND');
2694
2695	//This will give the distinct id_agente, give the id_grupo that goes
2696	//with it and then the number of times it occured. GROUP BY statement
2697	//is required if both DISTINCT() and COUNT() are in the statement
2698	switch ($config["dbtype"]) {
2699		case "mysql":
2700		case "postgresql":
2701			$sql = sprintf ('SELECT DISTINCT(id_agente) AS id_agente,
2702					COUNT(id_agente) AS count'.$field_extra.'
2703				FROM '.$event_table.'
2704				WHERE 1=1 %s %s
2705				GROUP BY id_agente'.$groupby_extra.'
2706				ORDER BY count DESC LIMIT 8', $url, $tags_condition);
2707			break;
2708		case "oracle":
2709			$sql = sprintf ('SELECT DISTINCT(id_agente) AS id_agente,
2710					id_grupo, COUNT(id_agente) AS count'.$field_extra.'
2711				FROM '.$event_table.'
2712				WHERE rownum <= 8 %s %s
2713				GROUP BY id_agente, id_grupo'.$groupby_extra.'
2714				ORDER BY count DESC', $url, $tags_condition);
2715			break;
2716	}
2717
2718	$result = db_get_all_rows_sql ($sql, false, false);
2719	if ($result === false) {
2720		$result = array();
2721	}
2722
2723	$system_events = 0;
2724	$other_events = 0;
2725
2726	foreach ($result as $row) {
2727		$row["id_grupo"] = agents_get_agent_group ($row["id_agente"]);
2728		if (!check_acl ($config["id_user"], $row["id_grupo"], "ER") == 1)
2729			continue;
2730
2731		if ($loop >= NUM_PIECES_PIE) {
2732			$other_events += $row["count"];
2733		}
2734		else {
2735			if ($row["id_agente"] == 0) {
2736				$system_events += $row["count"];
2737			}
2738			else {
2739				if ($meta) {
2740					$name = mb_substr (io_safe_output($row['agent_name']), 0, 14)." (".$row["count"].")";
2741				}
2742				else {
2743					$name = mb_substr (agents_get_name ($row["id_agente"], "lower"), 0, 14)." (".$row["count"].")";
2744				}
2745				$data[$name] = $row["count"];
2746			}
2747		}
2748		$loop++;
2749	}
2750
2751	if ($system_events > 0) {
2752		$name = __('SYSTEM')." (".$system_events.")";
2753		$data[$name] = $system_events;
2754	}
2755
2756	/*
2757	if ($other_events > 0) {
2758		$name = __('Other')." (".$other_events.")";
2759		$data[$name] = $other_events;
2760	}
2761	*/
2762
2763	// Sort the data
2764	arsort($data);
2765	if ($noWaterMark) {
2766		$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2767			'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2768	}
2769	else
2770	{
2771		$water_mark = array();
2772	}
2773
2774	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2775		__('Other'), '', $water_mark,
2776		$config['fontpath'], $config['font_size'], 1, 'bottom');
2777}
2778
2779function grafico_eventos_agente ($width = 300, $height = 200, $result = false, $meta = false, $history = false) {
2780	global $config;
2781	global $graphic_type;
2782
2783	//It was urlencoded, so we urldecode it
2784	//$url = html_entity_decode (rawurldecode ($url), ENT_QUOTES);
2785	$data = array ();
2786	$loop = 0;
2787
2788	if ($result === false) {
2789		$result = array();
2790	}
2791
2792	$system_events = 0;
2793	$other_events = 0;
2794	$total = array();
2795	$i = 0;
2796
2797	foreach ($result as $row) {
2798		if ($meta) {
2799			$count[] = $row["agent_name"];
2800		}
2801		else {
2802			if ($row["id_agente"] == 0) {
2803				$count[] = __('SYSTEM');
2804			}
2805			else
2806				$count[] = agents_get_name ($row["id_agente"]) ;
2807		}
2808
2809	}
2810
2811	$total = array_count_values($count);
2812
2813	foreach ($total as $key => $total) {
2814		if ($meta) {
2815			$name = $key." (".$total.")";
2816		}
2817		else {
2818			$name = $key." (".$total.")";
2819		}
2820		$data[$name] = $total;
2821	}
2822
2823	/*
2824	if ($other_events > 0) {
2825		$name = __('Other')." (".$other_events.")";
2826		$data[$name] = $other_events;
2827	}
2828	*/
2829
2830	// Sort the data
2831	arsort($data);
2832	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2833		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
2834
2835	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2836		__('Others'), '', $water_mark,
2837		$config['fontpath'], $config['font_size'], 1, 'bottom');
2838}
2839
2840/**
2841 * Print a pie graph with events data in 320x200 size
2842 *
2843 * @param string filter Filter for query in DB
2844 */
2845function grafico_eventos_total($filter = "", $width = 320, $height = 200, $noWaterMark = true) {
2846	global $config;
2847	global $graphic_type;
2848
2849	$filter = str_replace  ( "\\" , "", $filter);
2850
2851	// Add tags condition to filter
2852	$tags_condition = tags_get_acl_tags($config['id_user'], 0, 'ER', 'event_condition', 'AND');
2853	$filter .= $tags_condition;
2854
2855	$data = array ();
2856	$legend = array ();
2857	$total = 0;
2858
2859	$sql = "SELECT criticity, COUNT(id_evento) events
2860		FROM tevento
2861		GROUP BY criticity ORDER BY events DESC";
2862
2863	$criticities = db_get_all_rows_sql ($sql, false, false);
2864
2865	if (empty($criticities)) {
2866		$criticities = array();
2867		$colors = array();
2868	}
2869
2870	foreach ($criticities as $cr) {
2871		switch ($cr['criticity']) {
2872			case EVENT_CRIT_MAINTENANCE:
2873				$data[__('Maintenance')] = $cr['events'];
2874				$colors[__('Maintenance')] = COL_MAINTENANCE;
2875				break;
2876			case EVENT_CRIT_INFORMATIONAL:
2877				$data[__('Informational')] = $cr['events'];
2878				$colors[__('Informational')] = COL_INFORMATIONAL;
2879				break;
2880			case EVENT_CRIT_NORMAL:
2881				$data[__('Normal')] = $cr['events'];
2882				$colors[__('Normal')] = COL_NORMAL;
2883				break;
2884			case EVENT_CRIT_MINOR:
2885				$data[__('Minor')] = $cr['events'];
2886				$colors[__('Minor')] = COL_MINOR;
2887				break;
2888			case EVENT_CRIT_WARNING:
2889				$data[__('Warning')] = $cr['events'];
2890				$colors[__('Warning')] = COL_WARNING;
2891				break;
2892			case EVENT_CRIT_MAJOR:
2893				$data[__('Major')] = $cr['events'];
2894				$colors[__('Major')] = COL_MAJOR;
2895				break;
2896			case EVENT_CRIT_CRITICAL:
2897				$data[__('Critical')] = $cr['events'];
2898				$colors[__('Critical')] = COL_CRITICAL;
2899				break;
2900		}
2901	}
2902	if ($noWaterMark) {
2903		$water_mark = array(
2904			'file' => $config['homedir'] . "/images/logo_vertical_water.png",
2905			'url' => ui_get_full_url("/images/logo_vertical_water.png", false, false, false));
2906	}
2907	else {
2908		$water_mark = array();
2909	}
2910
2911	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2912		__('Other'), '', $water_mark,
2913		$config['fontpath'], $config['font_size'], 1, 'bottom', $colors);
2914}
2915
2916/**
2917 * Print a pie graph with events data of users
2918 *
2919 * @param integer height pie graph height
2920 * @param integer period time period
2921 */
2922function grafico_eventos_usuario ($width, $height) {
2923	global $config;
2924	global $graphic_type;
2925
2926	$data = array ();
2927	$max_items = 5;
2928	switch ($config["dbtype"]) {
2929		case "mysql":
2930		case "postgresql":
2931			$sql = sprintf ('SELECT COUNT(id_evento) events, id_usuario
2932				FROM tevento
2933				GROUP BY id_usuario
2934				ORDER BY 1 DESC LIMIT %d', $max_items);
2935			break;
2936		case "oracle":
2937			$sql = sprintf ('SELECT *
2938				FROM (SELECT COUNT(id_evento) events, id_usuario
2939					FROM tevento
2940					GROUP BY id_usuario
2941					ORDER BY 1 DESC)
2942				WHERE rownum <= %d', $max_items);
2943			break;
2944	}
2945	$events = db_get_all_rows_sql ($sql);
2946
2947	if ($events === false) {
2948		$events = array();
2949	}
2950
2951	foreach($events as $event) {
2952		if ($event['id_usuario'] == '0') {
2953			$data[__('System')] = $event['events'];
2954		}
2955		elseif ($event['id_usuario'] == '') {
2956			$data[__('System')] = $event['events'];
2957		}
2958		else {
2959			$data[$event['id_usuario']] = $event['events'];
2960		}
2961	}
2962
2963	$water_mark = array(
2964		'file' => $config['homedir'] .  "/images/logo_vertical_water.png",
2965		'url' => ui_get_full_url("/images/logo_vertical_water.png", false, false, false));
2966
2967	return pie3d_graph($config['flash_charts'], $data, $width, $height,
2968		__('Other'), '', $water_mark,
2969		$config['fontpath'], $config['font_size']);
2970}
2971
2972/**
2973 * Print a custom SQL-defined graph
2974 *
2975 * @param integer ID of report content, used to get SQL code to get information for graph
2976 * @param integer height graph height
2977 * @param integer width graph width
2978 * @param integer Graph type 1 vbar, 2 hbar, 3 pie
2979 */
2980function graph_custom_sql_graph ($id, $width, $height,
2981	$type = 'sql_graph_vbar', $only_image = false, $homeurl = '',
2982	$ttl = 1) {
2983
2984	global $config;
2985
2986	$report_content = db_get_row ('treport_content', 'id_rc', $id);
2987	if ($report_content["external_source"] != "") {
2988		$sql = io_safe_output ($report_content["external_source"]);
2989	}
2990	else {
2991		$sql = db_get_row('treport_custom_sql', 'id', $report_content["treport_custom_sql_id"]);
2992		$sql = io_safe_output($sql['sql']);
2993	}
2994
2995	if (($config['metaconsole'] == 1) && defined('METACONSOLE')) {
2996		$metaconsole_connection = enterprise_hook('metaconsole_get_connection', array($report_content['server_name']));
2997
2998		if ($metaconsole_connection === false) {
2999			return false;
3000		}
3001
3002		if (enterprise_hook('metaconsole_load_external_db', array($metaconsole_connection)) != NOERR) {
3003			//ui_print_error_message ("Error connecting to ".$server_name);
3004			return false;
3005		}
3006	}
3007
3008
3009	switch ($config["dbtype"]) {
3010		case "mysql":
3011		case "postgresql":
3012			break;
3013		case "oracle":
3014			$sql = str_replace(";", "", $sql);
3015			break;
3016	}
3017
3018
3019	$data_result = db_get_all_rows_sql ($sql);
3020
3021	if (($config['metaconsole'] == 1) && defined('METACONSOLE'))
3022		enterprise_hook('metaconsole_restore_db');
3023
3024	if ($data_result === false)
3025		$data_result = array ();
3026
3027	$data = array ();
3028
3029	$count = 0;
3030	foreach ($data_result as $data_item) {
3031		$count++;
3032		$value = 0;
3033		if (!empty($data_item["value"])) {
3034			$value = $data_item["value"];
3035		}
3036		$label = __('Data');
3037		if (!empty($data_item["label"])) {
3038			$label = $data_item["label"];
3039		}
3040		switch ($type) {
3041			case 'sql_graph_vbar': // vertical bar
3042			case 'sql_graph_hbar': // horizontal bar
3043				$data[$label]['g'] = $value;
3044				break;
3045			case 'sql_graph_pie': // Pie
3046				$data[$label] = $value;
3047				break;
3048		}
3049	}
3050
3051	$flash_charts = $config['flash_charts'];
3052
3053
3054	if ($only_image) {
3055		$flash_charts = false;
3056	}
3057
3058	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
3059		'url' => ui_get_full_url("/images/logo_vertical_water.png", false, false, false));
3060
3061	switch ($type) {
3062		case 'sql_graph_vbar': // vertical bar
3063			return vbar_graph($flash_charts, $data, $width, $height, array(),
3064				array(), "", "", $homeurl, $water_mark,
3065				$config['fontpath'], $config['font_size'], false, $ttl);
3066			break;
3067		case 'sql_graph_hbar': // horizontal bar
3068			return hbar_graph($flash_charts, $data, $width, $height, array(),
3069				array(), "", "", true, $homeurl, $water_mark,
3070				$config['fontpath'], $config['font_size'], false, $ttl);
3071			break;
3072		case 'sql_graph_pie': // Pie
3073			return pie3d_graph($flash_charts, $data, $width, $height, __("other"), $homeurl,
3074				$water_mark, $config['fontpath'], '', $ttl);
3075			break;
3076	}
3077}
3078
3079/**
3080 * Print a static graph with event data of agents
3081 *
3082 * @param integer id_agent Agent ID
3083 * @param integer width pie graph width
3084 * @param integer height pie graph height
3085 * @param integer period time period
3086 * @param string homeurl
3087 * @param bool return or echo the result
3088 */
3089function graph_graphic_agentevents ($id_agent, $width, $height, $period = 0, $homeurl, $return = false) {
3090	global $config;
3091	global $graphic_type;
3092
3093
3094	$data = array ();
3095
3096	$resolution = $config['graph_res'] * ($period * 2 / $width); // Number of "slices" we want in graph
3097
3098	$interval = (int) ($period / $resolution);
3099	$date = get_system_time ();
3100	$datelimit = $date - $period;
3101	$periodtime = floor ($period / $interval);
3102	$time = array ();
3103	$data = array ();
3104	$legend = array();
3105	$full_legend = array();
3106
3107	$cont = 0;
3108	for ($i = 0; $i < $interval; $i++) {
3109		$bottom = $datelimit + ($periodtime * $i);
3110		if (! $graphic_type) {
3111			if ($config['flash_charts']) {
3112				$name = date('H:i', $bottom);
3113			}
3114			else {
3115				$name = date('H\h', $bottom);
3116			}
3117		}
3118		else {
3119			$name = $bottom;
3120		}
3121
3122		// Show less values in legend
3123		if ($cont == 0 or $cont % 2)
3124			$legend[$cont] = $name;
3125
3126		$full_legend[$cont] = $name;
3127
3128		$top = $datelimit + ($periodtime * ($i + 1));
3129		$event = db_get_row_filter ('tevento',
3130			array ('id_agente' => $id_agent,
3131				'utimestamp > '.$bottom,
3132				'utimestamp < '.$top), 'criticity, utimestamp');
3133
3134		if (!empty($event['utimestamp'])) {
3135			$data[$cont]['utimestamp'] = $periodtime;
3136			switch ($event['criticity']) {
3137				case EVENT_CRIT_WARNING:
3138					$data[$cont]['data'] = 2;
3139					break;
3140				case EVENT_CRIT_CRITICAL:
3141					$data[$cont]['data'] = 3;
3142					break;
3143				default:
3144					$data[$cont]['data'] = 1;
3145					break;
3146			}
3147		}
3148		else {
3149			$data[$cont]['utimestamp'] = $periodtime;
3150			$data[$cont]['data'] = 1;
3151		}
3152		$cont++;
3153	}
3154
3155	$colors = array(1 => COL_NORMAL, 2 => COL_WARNING, 3 => COL_CRITICAL, 4 => COL_UNKNOWN);
3156
3157	// Draw slicebar graph
3158	if ($config['flash_charts']) {
3159		$out = flot_slicesbar_graph($data, $period, $width, $height, $full_legend, $colors, $config['fontpath'], $config['round_corner'], $homeurl);
3160	}
3161	else {
3162		$out = slicesbar_graph($data, $period, $width, $height, $colors, $config['fontpath'], $config['round_corner'], $homeurl);
3163
3164		// Draw legend
3165		$out .=  "<br>";
3166		$out .=  "&nbsp;";
3167		foreach ($legend as $hour) {
3168			$out .=  "<span style='font-size: 6pt'>" . $hour . "</span>";
3169			$out .=  "&nbsp;";
3170		}
3171	}
3172
3173	if ($return) {
3174		return $out;
3175	}
3176	else {
3177		echo $out;
3178	}
3179}
3180
3181// Prints an error image
3182function fs_error_image ($width = 300, $height = 110) {
3183	global $config;
3184
3185	return graph_nodata_image($width, $height, 'area');
3186}
3187
3188function grafico_modulo_boolean_data ($agent_module_id, $period, $show_events,
3189	$unit_name, $show_alerts, $avg_only = 0,
3190	$date = 0, $series_suffix = '', $series_suffix_str = '', $show_unknown = false) {
3191
3192	global $config;
3193	global $chart;
3194	global $color;
3195	global $legend;
3196	global $long_index;
3197	global $series_type;
3198	global $chart_extra_data;
3199
3200
3201	$chart = array();
3202	$color = array();
3203	$legend = array();
3204	$long_index = array();
3205	$start_unknown = false;
3206
3207	// Set variables
3208	if ($date == 0) $date = get_system_time();
3209	$datelimit = $date - $period;
3210	$search_in_history_db = db_search_in_history_db($datelimit);
3211	$resolution = $config['graph_res'] * 50; //Number of points of the graph
3212	$interval = (int) ($period / $resolution);
3213	$agent_name = modules_get_agentmodule_agent_name ($agent_module_id);
3214	$agent_id = agents_get_agent_id ($agent_name);
3215	$module_name = modules_get_agentmodule_name ($agent_module_id);
3216	$id_module_type = modules_get_agentmodule_type ($agent_module_id);
3217	$module_type = modules_get_moduletype_name ($id_module_type);
3218	$uncompressed_module = is_module_uncompressed ($module_type);
3219	if ($uncompressed_module) {
3220		$avg_only = 1;
3221	}
3222	$search_in_history_db = db_search_in_history_db($datelimit);
3223
3224	// Get event data (contains alert data too)
3225	if ($show_unknown == 1 || $show_events == 1 || $show_alerts == 1) {
3226		$events = db_get_all_rows_filter('tevento',
3227			array ('id_agentmodule' => $agent_module_id,
3228				"utimestamp > $datelimit",
3229				"utimestamp < $date",
3230				'order' => 'utimestamp ASC'),
3231			array ('evento', 'utimestamp', 'event_type', 'id_evento'));
3232
3233		// Get the last event after inverval to know if graph start on unknown
3234		$prev_event = db_get_row_filter ('tevento',
3235			array ('id_agentmodule' => $agent_module_id,
3236				"utimestamp <= $datelimit",
3237				'order' => 'utimestamp DESC'));
3238		if (isset($prev_event['event_type']) && $prev_event['event_type'] == 'going_unknown') {
3239			$start_unknown = true;
3240		}
3241
3242		if ($events === false) {
3243			$events = array ();
3244		}
3245	}
3246
3247	// Get module data
3248	$data = db_get_all_rows_filter ('tagente_datos',
3249		array ('id_agente_modulo' => $agent_module_id,
3250			"utimestamp > $datelimit",
3251			"utimestamp < $date",
3252			'order' => 'utimestamp ASC'),
3253		array ('datos', 'utimestamp'), 'AND', $search_in_history_db);
3254	if ($data === false) {
3255		$data = array ();
3256	}
3257
3258	// Uncompressed module data
3259	if ($uncompressed_module) {
3260		$min_necessary = 1;
3261
3262	// Compressed module data
3263	}
3264	else {
3265		// Get previous data
3266		$previous_data = modules_get_previous_data ($agent_module_id, $datelimit);
3267		if ($previous_data !== false) {
3268			$previous_data['utimestamp'] = $datelimit;
3269			array_unshift ($data, $previous_data);
3270		}
3271
3272		// Get next data
3273		$nextData = modules_get_next_data ($agent_module_id, $date);
3274		if ($nextData !== false) {
3275			array_push ($data, $nextData);
3276		}
3277		else if (count ($data) > 0) {
3278			// Propagate the last known data to the end of the interval
3279			$nextData = array_pop ($data);
3280			array_push ($data, $nextData);
3281			$nextData['utimestamp'] = $date;
3282			array_push ($data, $nextData);
3283		}
3284
3285		$min_necessary = 2;
3286	}
3287
3288	// Check available data
3289	if (count ($data) < $min_necessary) {
3290		if (!$graphic_type) {
3291			return fs_error_image ();
3292		}
3293		graphic_error ();
3294	}
3295
3296	if (empty($unit_name)) {
3297		$unit = modules_get_unit($agent_module_id);
3298	}
3299	else
3300		$unit = $unit_name;
3301
3302	// Data iterator
3303	$j = 0;
3304
3305	// Event iterator
3306	$k = 0;
3307
3308	// Set initial conditions
3309	if ($data[0]['utimestamp'] == $datelimit) {
3310		$previous_data = $data[0]['datos'];
3311		$j++;
3312	}
3313	else {
3314		$previous_data = 0;
3315	}
3316
3317	$max_value = 0;
3318
3319	// Calculate chart data
3320	$last_known = $previous_data;
3321	for ($i = 0; $i <= $resolution; $i++) {
3322		$timestamp = $datelimit + ($interval * $i);
3323
3324		$zero = 0;
3325		$total = 0;
3326		$count = 0;
3327
3328		// Read data that falls in the current interval
3329		while (isset ($data[$j]) &&
3330			$data[$j]['utimestamp'] >= $timestamp &&
3331			$data[$j]['utimestamp'] <= ($timestamp + $interval)) {
3332			if ($data[$j]['datos'] == 0) {
3333				$zero = 1;
3334			}
3335			else {
3336				$total += $data[$j]['datos'];
3337				$count++;
3338			}
3339
3340			$last_known = $data[$j]['datos'];
3341			$j++;
3342		}
3343
3344		// Average
3345		if ($count > 0) {
3346			$total /= $count;
3347		}
3348
3349		// Read events and alerts that fall in the current interval
3350		$event_value = 0;
3351		$alert_value = 0;
3352		$unknown_value = 0;
3353		$is_unknown = false;
3354		// Is the first point of a unknown interval
3355		$first_unknown = false;
3356
3357		$event_ids = array();
3358		$alert_ids = array();
3359		while (isset ($events[$k]) &&
3360			$events[$k]['utimestamp'] >= $timestamp &&
3361			$events[$k]['utimestamp'] < ($timestamp + $interval)) {
3362			if ($show_events == 1) {
3363				$event_value++;
3364				$event_ids[] = $events[$k]['id_evento'];
3365			}
3366			if ($show_alerts == 1 && substr ($events[$k]['event_type'], 0, 5) == 'alert') {
3367				$alert_value++;
3368				$alert_ids[] = $events[$k]['id_evento'];
3369			}
3370			if ($show_unknown) {
3371				if ($events[$k]['event_type'] == 'going_unknown') {
3372					if ($is_unknown == false) {
3373						$first_unknown = true;
3374					}
3375					$is_unknown = true;
3376				}
3377				else if (substr ($events[$k]['event_type'], 0, 5) == 'going') {
3378					$is_unknown = false;
3379				}
3380			}
3381			$k++;
3382		}
3383
3384		// In some cases, can be marked as known because a recovery event
3385		// was found in same interval. For this cases first_unknown is
3386		// checked too
3387		if ($is_unknown || $first_unknown) {
3388			$unknown_value++;
3389		}
3390
3391		// Set the title and time format
3392		if ($period <= SECONDS_6HOURS) {
3393			$time_format = 'H:i:s';
3394		}
3395		elseif ($period < SECONDS_1DAY) {
3396			$time_format = 'H:i';
3397		}
3398		elseif ($period < SECONDS_15DAYS) {
3399			$time_format = 'M d H:i';
3400		}
3401		elseif ($period < SECONDS_1MONTH) {
3402			$time_format = 'M d H\h';
3403		}
3404		else {
3405			$time_format = 'M d H\h';
3406		}
3407
3408		$timestamp_short = date($time_format, $timestamp);
3409		$long_index[$timestamp_short] = date(
3410			html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp);
3411		$timestamp = $timestamp_short;
3412		/////////////////////////////////////////////////////////////////
3413
3414		if ($total > $max_value) {
3415			$max_value = $total;
3416		}
3417
3418		if ($show_events) {
3419			if (!isset($chart[$timestamp]['event'.$series_suffix])) {
3420				$chart[$timestamp]['event'.$series_suffix] = 0;
3421			}
3422
3423			$chart[$timestamp]['event'.$series_suffix] += $event_value;
3424			$series_type['event'.$series_suffix] = 'points';
3425		}
3426		if ($show_alerts) {
3427			if (!isset($chart[$timestamp]['alert'.$series_suffix])) {
3428				$chart[$timestamp]['alert'.$series_suffix] = 0;
3429			}
3430
3431			$chart[$timestamp]['alert'.$series_suffix] += $alert_value;
3432			$series_type['alert'.$series_suffix] = 'points';
3433		}
3434
3435		//The order filling the array is very important to get the same colors
3436		//in legends and graphs!!!
3437		//Boolean graph doesn't have max!!!
3438		/*if (!$avg_only) {
3439			$chart[$timestamp]['max'.$series_suffix] = 0;
3440		}*/
3441
3442		// Data and zeroes (draw a step)
3443		if ($zero == 1 && $count > 0) {
3444
3445			//New code set 0 if there is a 0
3446			//Please check the incident #665
3447			//http://192.168.50.2/integria/index.php?sec=incidents&sec2=operation/incidents/incident_dashboard_detail&id=665
3448			$chart[$timestamp]['sum'.$series_suffix] = 0;
3449		}
3450		else if ($zero == 1) { // Just zeros
3451			$chart[$timestamp]['sum'.$series_suffix] = 0;
3452		}
3453		else if ($count > 0) { // No zeros
3454			$chart[$timestamp]['sum'.$series_suffix] = $total;
3455		}
3456		else { // Compressed data
3457			if ($uncompressed_module || ($timestamp > time ()) || $is_unknown) {
3458				$chart[$timestamp]['sum'.$series_suffix] = 0;
3459			}
3460			else {
3461				$chart[$timestamp]['sum'.$series_suffix] = $last_known;
3462			}
3463		}
3464
3465		if ($show_unknown) {
3466			if (!isset($chart[$timestamp]['unknown'.$series_suffix])) {
3467				$chart[$timestamp]['unknown'.$series_suffix] = 0;
3468			}
3469
3470			$chart[$timestamp]['unknown'.$series_suffix] = $unknown_value;
3471			$series_type['unknown'.$series_suffix] = 'area';
3472		}
3473
3474		$series_type['sum' . $series_suffix] = 'boolean';
3475
3476		//Boolean graph doesn't have min!!!
3477		/*if (!$avg_only) {
3478			$chart[$timestamp]['min'.$series_suffix] = 0;
3479		}*/
3480
3481		if (!empty($event_ids)) {
3482			$chart_extra_data[count($chart)-1]['events'] = implode(',',$event_ids);
3483		}
3484		if (!empty($alert_ids)) {
3485			$chart_extra_data[count($chart)-1]['alerts'] = implode(',',$alert_ids);
3486		}
3487
3488	}
3489
3490	// Get min, max and avg (less efficient but centralized for all modules and reports)
3491	$graph_stats = get_statwin_graph_statistics($chart, $series_suffix);
3492
3493	// Fix event and alert scale
3494	foreach ($chart as $timestamp => $chart_data) {
3495		if ($show_events) {
3496			if ($chart_data['event'.$series_suffix] > 0) {
3497				$chart[$timestamp]['event'.$series_suffix] = $max_value * 1.2;
3498			}
3499		}
3500		if ($show_alerts) {
3501			if ($chart_data['alert'.$series_suffix] > 0) {
3502				$chart[$timestamp]['alert'.$series_suffix] = $max_value * 1.10;
3503			}
3504		}
3505		if ($show_unknown) {
3506			if ($chart_data['unknown'.$series_suffix] > 0) {
3507				$chart[$timestamp]['unknown'.$series_suffix] = $max_value * 1.05;
3508			}
3509		}
3510	}
3511
3512	///////////////////////////////////////////////////
3513	// Set the title and time format
3514	if ($period <= SECONDS_6HOURS) {
3515		$time_format = 'H:i:s';
3516	}
3517	elseif ($period < SECONDS_1DAY) {
3518		$time_format = 'H:i';
3519	}
3520	elseif ($period < SECONDS_15DAYS) {
3521		$time_format = 'M d H:i';
3522	}
3523	elseif ($period < SECONDS_1MONTH) {
3524		$time_format = 'M d H\h';
3525	}
3526	else {
3527		$time_format = 'M d H\h';
3528	}
3529
3530	// Flash chart
3531	$caption = __('Max. Value').$series_suffix_str . ': ' . $graph_stats['sum']['max'] . '    ' . __('Avg. Value').$series_suffix_str .
3532	': ' . $graph_stats['sum']['avg'] . '    ' . __('Min. Value').$series_suffix_str . ': ' . $graph_stats['sum']['min'] . '   ' . __('Units').$series_suffix_str . ': ' . $unit;
3533
3534	/////////////////////////////////////////////////////////////////////////////////////////
3535	if ($show_events) {
3536		$legend['event'.$series_suffix] = __('Events').$series_suffix_str;
3537		$chart_extra_data['legend_events'] = $legend['event'.$series_suffix];
3538	}
3539	if ($show_alerts) {
3540		$legend['alert'.$series_suffix] = __('Alerts').$series_suffix_str;
3541		$chart_extra_data['legend_alerts'] = $legend['alert'.$series_suffix];
3542	}
3543
3544	if (!$avg_only) {
3545		//Boolean graph doesn't have max!!!
3546		//$legend['max'.$series_suffix] = __('Max').$series_suffix_str .': '.__('Last').': '.$graph_stats['max']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['max']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['max']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['max']['min'].' '.$unit;
3547		$legend['sum'.$series_suffix] = __('Avg').$series_suffix_str.': '.__('Last').': '.$graph_stats['sum']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['sum']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['sum']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['sum']['min'].' '.$unit;
3548		//Boolean graph doesn't have min!!!
3549		//$legend['min'.$series_suffix] = __('Min').$series_suffix_str .': '.__('Last').': '.$graph_stats['min']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['min']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['min']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['min']['min'].' '.$unit;
3550	}
3551	else {
3552		$legend['sum'.$series_suffix] = __('Avg').$series_suffix_str.': '.__('Last').': '.$graph_stats['sum']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['sum']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['sum']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['sum']['min'].' '.$unit;
3553
3554	}
3555
3556	if ($show_unknown) {
3557		$legend['unknown'.$series_suffix] = __('Unknown').$series_suffix_str;
3558		$chart_extra_data['legend_unknown'] = $legend['unknown'.$series_suffix];
3559	}
3560	//$legend['baseline'.$series_suffix] = __('Baseline').$series_suffix_str;
3561	/////////////////////////////////////////////////////////////////////////////////////////
3562	if ($show_events) {
3563		$color['event'.$series_suffix] =
3564			array('border' => '#ff0000', 'color' => '#ff0000',
3565				'alpha' => CHART_DEFAULT_ALPHA);
3566	}
3567	if ($show_alerts) {
3568		$color['alert'.$series_suffix] =
3569			array('border' => '#ff7f00', 'color' => '#ff7f00',
3570				'alpha' => CHART_DEFAULT_ALPHA);
3571	}
3572	$color['max'.$series_suffix] =
3573		array('border' => '#000000', 'color' => $config['graph_color3'],
3574			'alpha' => CHART_DEFAULT_ALPHA);
3575	$color['sum'.$series_suffix] =
3576		array('border' => '#000000', 'color' => $config['graph_color2'],
3577			'alpha' => CHART_DEFAULT_ALPHA);
3578	$color['min'.$series_suffix] =
3579		array('border' => '#000000', 'color' => $config['graph_color1'],
3580			'alpha' => CHART_DEFAULT_ALPHA);
3581	if ($show_unknown) {
3582		$color['unknown'.$series_suffix] =
3583			array('border' => '#999999', 'color' => '#999999',
3584				'alpha' => CHART_DEFAULT_ALPHA);
3585	}
3586	//$color['baseline'.$series_suffix] = array('border' => null, 'color' => '#0097BD', 'alpha' => 10);
3587}
3588
3589function grafico_modulo_boolean ($agent_module_id, $period, $show_events,
3590	$width, $height , $title, $unit_name, $show_alerts, $avg_only = 0, $pure=0,
3591	$date = 0, $only_image = false, $homeurl = '', $adapt_key = '', $compare = false,
3592	$show_unknown = false, $menu = true) {
3593
3594	global $config;
3595	global $graphic_type;
3596
3597	$flash_chart = $config['flash_charts'];
3598
3599	global $chart;
3600	global $color;
3601	global $color_prev;
3602	global $legend;
3603	global $long_index;
3604	global $series_type;
3605	global $chart_extra_data;
3606
3607	if (empty($unit_name)) {
3608		$unit = modules_get_unit($agent_module_id);
3609	}
3610	else
3611		$unit = $unit_name;
3612
3613
3614	$series_suffix_str = '';
3615	if ($compare !== false) {
3616		$series_suffix = '2';
3617		$series_suffix_str = ' (' . __('Previous') . ')';
3618		// Build the data of the previous period
3619		grafico_modulo_boolean_data ($agent_module_id, $period, $show_events,
3620			$unit_name, $show_alerts, $avg_only, $date-$period, $series_suffix,
3621			$series_suffix_str, $show_unknown);
3622		switch ($compare) {
3623			case 'separated':
3624				// Store the chart calculated
3625				$chart_prev = $chart;
3626				$legend_prev = $legend;
3627				$long_index_prev = $long_index;
3628				$series_type_prev = $series_type;
3629				$chart_extra_data_prev = $chart_extra_data;
3630				$chart_extra_data = array();
3631				$color_prev = $color;
3632				break;
3633			case 'overlapped':
3634				// Store the chart calculated deleting index, because will be over the current period
3635				$chart_prev = array_values($chart);
3636				$legend_prev = $legend;
3637				$series_type_prev = $series_type;
3638				$color_prev = $color;
3639				foreach ($color_prev as $k => $col) {
3640					$color_prev[$k]['color'] = '#' . get_complementary_rgb($color_prev[$k]['color']);
3641				}
3642				break;
3643		}
3644	}
3645
3646	grafico_modulo_boolean_data ($agent_module_id, $period, $show_events,
3647		$unit_name, $show_alerts, $avg_only, $date, '', '', $show_unknown);
3648
3649	if ($compare === 'overlapped') {
3650		$i = 0;
3651		foreach($chart as $k => $v) {
3652			$chart[$k] = array_merge($v, $chart_prev[$i]);
3653			$i++;
3654		}
3655
3656		$legend = array_merge($legend, $legend_prev);
3657		$color = array_merge($color, $color_prev);
3658	}
3659
3660	if ($only_image) {
3661		$flash_chart = false;
3662	}
3663
3664	$water_mark = array(
3665		'file' => $config['homedir'] .  "/images/logo_vertical_water.png",
3666		'url' => ui_get_full_url("/images/logo_vertical_water.png",
3667		false, false, false));
3668
3669	if ($config['type_module_charts'] === 'area') {
3670		if ($compare === 'separated') {
3671			return area_graph($flash_chart, $chart, $width, $height/2, $color, $legend,
3672				$long_index, ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3673				"", $unit, $homeurl, $water_mark,
3674				$config['fontpath'], $config['font_size'], $unit, 1, $series_type,
3675				$chart_extra_data, 0, 0, $adapt_key, false, $series_suffix_str, $menu).
3676				'<br>'.
3677				area_graph($flash_chart, $chart_prev, $width, $height/2, $color_prev, $legend_prev,
3678				$long_index_prev, ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3679				"", $unit, $homeurl, $water_mark,
3680				$config['fontpath'], $config['font_size'], $unit, 1, $series_type_prev,
3681				$chart_extra_data_prev, 0, 0, $adapt_key, false, $series_suffix_str, $menu);
3682		}
3683		else {
3684			return area_graph($flash_chart, $chart, $width, $height, $color, $legend,
3685				$long_index, ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3686				"", $unit, $homeurl, $water_mark,
3687				$config['fontpath'], $config['font_size'], $unit, 1, $series_type,
3688				$chart_extra_data, 0, 0, $adapt_key, false, $series_suffix_str, $menu);
3689		}
3690	}
3691	elseif ($config['type_module_charts'] === 'line') {
3692		if ($compare === 'separated') {
3693			return
3694				line_graph($flash_chart, $chart, $width, $height/2, $color,
3695					$legend, $long_index,
3696					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3697					"", $unit, $water_mark, $config['fontpath'],
3698					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor).
3699				'<br>'.
3700				line_graph($flash_chart, $chart_prev, $width, $height/2, $color,
3701					$legend, $long_index,
3702					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3703					"", $unit, $water_mark, $config['fontpath'],
3704					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor);
3705		}
3706		else {
3707			// Color commented not to restrict serie colors
3708			return
3709				line_graph($flash_chart, $chart, $width, $height, $color,
3710					$legend, $long_index,
3711					ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3712					"", $unit, $water_mark, $config['fontpath'],
3713					$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor);
3714		}
3715	}
3716}
3717
3718
3719/**
3720 * Print an area graph with netflow aggregated
3721 */
3722
3723function graph_netflow_aggregate_area ($data, $period, $width, $height, $unit = '', $ttl = 1, $only_image = false) {
3724	global $config;
3725	global $graphic_type;
3726
3727	if (empty ($data)) {
3728		echo fs_error_image ();
3729		return;
3730	}
3731
3732
3733	if ($period <= SECONDS_6HOURS) {
3734		$chart_time_format = 'H:i:s';
3735	}
3736	elseif ($period < SECONDS_1DAY) {
3737		$chart_time_format = 'H:i';
3738	}
3739	elseif ($period < SECONDS_15DAYS) {
3740		$chart_time_format = 'M d H:i';
3741	}
3742	elseif ($period < SECONDS_1MONTH) {
3743		$chart_time_format = 'M d H\h';
3744	}
3745	else {
3746		$chart_time_format = 'M d H\h';
3747	}
3748
3749	// Calculate source indexes
3750	$i = 0;
3751	$sources = array ();
3752	foreach ($data['sources'] as $source => $value) {
3753		$source_indexes[$source] = $i;
3754		$sources[$i] = $source;
3755		$i++;
3756	}
3757
3758	// Add sources to chart
3759	$chart = array ();
3760	foreach ($data['data'] as $timestamp => $data) {
3761		$chart_date = date ($chart_time_format, $timestamp);
3762		$chart[$chart_date] = array ();
3763		foreach ($source_indexes as $source => $index) {
3764			$chart[$chart_date][$index] = 0;
3765		}
3766		foreach ($data as $source => $value) {
3767			$chart[$chart_date][$source_indexes[$source]] = $value;
3768		}
3769	}
3770
3771
3772	$flash_chart = $config['flash_charts'];
3773	if ($only_image) {
3774		$flash_chart = false;
3775	}
3776
3777	if ($config['homeurl'] != '') {
3778		$homeurl = $config['homeurl'];
3779	}
3780	else {
3781		$homeurl = '';
3782	}
3783
3784	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
3785		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
3786
3787
3788	return area_graph($flash_chart, $chart, $width, $height, array (), $sources,
3789		array (), ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3790		"", $unit, $homeurl,
3791		$config['homedir'] .  "/images/logo_vertical_water.png",
3792		$config['fontpath'], $config['font_size'], $unit, 2);
3793}
3794
3795
3796
3797/**
3798 * Print an area graph with netflow total
3799 */
3800function graph_netflow_total_area ($data, $period, $width, $height, $unit = '', $ttl = 1, $only_image = false) {
3801	global $config;
3802	global $graphic_type;
3803
3804	if (empty ($data)) {
3805		echo fs_error_image ();
3806		return;
3807	}
3808
3809	if ($period <= SECONDS_6HOURS) {
3810		$chart_time_format = 'H:i:s';
3811	}
3812	elseif ($period < SECONDS_1DAY) {
3813		$chart_time_format = 'H:i';
3814	}
3815	elseif ($period < SECONDS_15DAYS) {
3816		$chart_time_format = 'M d H:i';
3817	}
3818	elseif ($period < SECONDS_1MONTH) {
3819		$chart_time_format = 'M d H\h';
3820	}
3821	else {
3822		$chart_time_format = 'M d H\h';
3823	}
3824
3825	// Calculate min, max and avg values
3826	$avg = 0;
3827	foreach ($data as $timestamp => $value) {
3828		$max = $value['data'];
3829		$min = $value['data'];
3830		break;
3831	}
3832
3833	// Populate chart
3834	$count = 0;
3835	$chart = array ();
3836	foreach ($data as $timestamp => $value) {
3837		$chart[date ($chart_time_format, $timestamp)] = $value;
3838		if ($value['data'] > $max) {
3839			$max = $value['data'];
3840		}
3841		if ($value['data'] < $min) {
3842			$min = $value['data'];
3843		}
3844		$avg += $value['data'];
3845		$count++;
3846	}
3847	if ($count > 0) {
3848		$avg /= $count;
3849	}
3850
3851	$flash_chart = $config['flash_charts'];
3852	if ($only_image) {
3853		$flash_chart = false;
3854	}
3855
3856	if ($config['homeurl'] != '') {
3857		$homeurl = $config['homeurl'];
3858	}
3859	else {
3860		$homeurl = '';
3861	}
3862
3863	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
3864		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
3865
3866	$legend = array (__('Max.') . ' ' . format_numeric($max) . ' ' . __('Min.') . ' ' . format_numeric($min) . ' ' . __('Avg.') . ' ' . format_numeric ($avg));
3867	return area_graph($flash_chart, $chart, $width, $height, array (), $legend,
3868		array (), ui_get_full_url("images/image_problem.opaque.png", false, false, false),
3869		"", "", $homeurl, $water_mark,
3870		$config['fontpath'], $config['font_size'], $unit, $ttl);
3871}
3872
3873/**
3874 * Print a pie graph with netflow aggregated
3875 */
3876function graph_netflow_aggregate_pie ($data, $aggregate, $ttl = 1, $only_image = false) {
3877	global $config;
3878	global $graphic_type;
3879
3880	if (empty ($data)) {
3881		return fs_error_image ();
3882	}
3883
3884	$i = 0;
3885	$values = array();
3886	$agg = '';
3887	while (isset ($data[$i])) {
3888		$agg = $data[$i]['agg'];
3889		if (!isset($values[$agg])) {
3890			$values[$agg] = $data[$i]['data'];
3891		}
3892		else {
3893			$values[$agg] += $data[$i]['data'];
3894		}
3895		$i++;
3896	}
3897
3898	$flash_chart = $config['flash_charts'];
3899	if ($only_image) {
3900		$flash_chart = false;
3901	}
3902
3903	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
3904		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
3905
3906	return pie3d_graph($flash_chart, $values, 370, 200,
3907		__('Other'), $config['homeurl'], $water_mark,
3908		$config['fontpath'], $config['font_size'], $ttl);
3909}
3910
3911/**
3912 * Print a circular graph with the data transmitted between IPs
3913 */
3914function graph_netflow_circular_mesh ($data, $unit, $radius = 700) {
3915	global $config;
3916
3917	if (empty($data) || empty($data['elements']) || empty($data['matrix'])) {
3918		return fs_error_image ();
3919	}
3920
3921	include_once($config['homedir'] . "/include/graphs/functions_d3.php");
3922
3923	return d3_relationship_graph ($data['elements'], $data['matrix'], $unit, $radius, true);
3924}
3925
3926/**
3927 * Print a rectangular graph with the traffic of the ports for each IP
3928 */
3929function graph_netflow_host_traffic ($data, $unit, $width = 700, $height = 700) {
3930	global $config;
3931
3932	if (empty ($data)) {
3933		return fs_error_image ();
3934	}
3935
3936	include_once($config['homedir'] . "/include/graphs/functions_d3.php");
3937
3938	return d3_tree_map_graph ($data, $width, $height, true);
3939}
3940
3941/**
3942 * Draw a graph of Module string data of agent
3943 *
3944 * @param integer id_agent_modulo Agent Module ID
3945 * @param integer show_event show event (1 or 0)
3946 * @param integer height graph height
3947 * @param integer width graph width
3948 * @param string title graph title
3949 * @param string unit_name String of unit name
3950 * @param integer show alerts (1 or 0)
3951 * @param integer avg_only calcules avg only (1 or 0)
3952 * @param integer pure Fullscreen (1 or 0)
3953 * @param integer date date
3954 */
3955function grafico_modulo_string ($agent_module_id, $period, $show_events,
3956	$width, $height , $title, $unit_name, $show_alerts, $avg_only = 0, $pure = 0,
3957	$date = 0, $only_image = false, $homeurl = '', $adapt_key = '', $ttl = 1, $menu = true) {
3958	global $config;
3959	global $graphic_type;
3960	global $max_value;
3961
3962
3963	// Set variables
3964	if ($date == 0)
3965		$date = get_system_time();
3966	$datelimit = $date - $period;
3967	$search_in_history_db = db_search_in_history_db($datelimit);
3968	$resolution = $config['graph_res'] * 50; //Number of points of the graph
3969	$interval = (int) ($period / $resolution);
3970	$agent_name = modules_get_agentmodule_agent_name ($agent_module_id);
3971	$agent_id = agents_get_agent_id ($agent_name);
3972	$module_name = modules_get_agentmodule_name ($agent_module_id);
3973	$id_module_type = modules_get_agentmodule_type ($agent_module_id);
3974	$module_type = modules_get_moduletype_name ($id_module_type);
3975	$uncompressed_module = is_module_uncompressed ($module_type);
3976	if ($uncompressed_module) {
3977		$avg_only = 1;
3978	}
3979	$search_in_history_db = db_search_in_history_db($datelimit);
3980
3981	// Get event data (contains alert data too)
3982	if ($show_events == 1 || $show_alerts == 1) {
3983		$events = db_get_all_rows_filter ('tevento',
3984			array ('id_agentmodule' => $agent_module_id,
3985				"utimestamp > $datelimit",
3986				"utimestamp < $date",
3987				'order' => 'utimestamp ASC'),
3988			array ('evento', 'utimestamp', 'event_type'));
3989		if ($events === false) {
3990			$events = array ();
3991		}
3992	}
3993
3994	// Get module data
3995	$data = db_get_all_rows_filter ('tagente_datos_string',
3996		array ('id_agente_modulo' => $agent_module_id,
3997			"utimestamp > $datelimit",
3998			"utimestamp < $date",
3999			'order' => 'utimestamp ASC'),
4000		array ('datos', 'utimestamp'), 'AND', $search_in_history_db);
4001	if ($data === false) {
4002		$data = array ();
4003	}
4004
4005	// Uncompressed module data
4006	if ($uncompressed_module) {
4007		$min_necessary = 1;
4008	}
4009	else {
4010		// Compressed module data
4011
4012		// Get previous data
4013		$previous_data = modules_get_previous_data ($agent_module_id, $datelimit, 1);
4014		if ($previous_data !== false) {
4015			$previous_data['utimestamp'] = $datelimit;
4016			array_unshift ($data, $previous_data);
4017		}
4018
4019		// Get next data
4020		$nextData = modules_get_next_data ($agent_module_id, $date, 1);
4021		if ($nextData !== false) {
4022			array_push ($data, $nextData);
4023		}
4024		else if (count ($data) > 0) {
4025			// Propagate the last known data to the end of the interval
4026			$nextData = array_pop ($data);
4027			array_push ($data, $nextData);
4028			$nextData['utimestamp'] = $date;
4029			array_push ($data, $nextData);
4030		}
4031
4032		$min_necessary = 2;
4033	}
4034
4035	// Check available data
4036	if (count ($data) < $min_necessary) {
4037		if (!$graphic_type) {
4038			return fs_error_image ($width, $height);
4039		}
4040		graphic_error ();
4041	}
4042
4043	// Data iterator
4044	$j = 0;
4045
4046	// Event iterator
4047	$k = 0;
4048
4049	// Set initial conditions
4050	$chart = array();
4051	if ($data[0]['utimestamp'] == $datelimit) {
4052		$previous_data = 1;
4053		$j++;
4054	}
4055	else {
4056		$previous_data = 0;
4057	}
4058
4059	// Calculate chart data
4060	$last_known = $previous_data;
4061	for ($i = 0; $i < $resolution; $i++) {
4062		$timestamp = $datelimit + ($interval * $i);
4063
4064		$count = 0;
4065		$total = 0;
4066		// Read data that falls in the current interval
4067		while (isset($data[$j]) &&
4068			isset ($data[$j]) !== null &&
4069			$data[$j]['utimestamp'] >= $timestamp &&
4070			$data[$j]['utimestamp'] <= ($timestamp + $interval)) {
4071
4072			// ---------------------------------------------------------
4073			// FIX TICKET #1749
4074			$last_known = $count;
4075			// ---------------------------------------------------------
4076			$count++;
4077			$j++;
4078		}
4079
4080		if ($max_value < $count) {
4081			$max_value = $count;
4082		}
4083
4084		// Read events and alerts that fall in the current interval
4085		$event_value = 0;
4086		$alert_value = 0;
4087		while (isset ($events[$k]) && $events[$k]['utimestamp'] >= $timestamp && $events[$k]['utimestamp'] <= ($timestamp + $interval)) {
4088			if ($show_events == 1) {
4089				$event_value++;
4090			}
4091			if ($show_alerts == 1 && substr ($events[$k]['event_type'], 0, 5) == 'alert') {
4092				$alert_value++;
4093			}
4094			$k++;
4095		}
4096
4097		/////////////////////////////////////////////////////////////////
4098		// Set the title and time format
4099		if ($period <= SECONDS_6HOURS) {
4100			$time_format = 'H:i:s';
4101		}
4102		elseif ($period < SECONDS_1DAY) {
4103			$time_format = 'H:i';
4104		}
4105		elseif ($period < SECONDS_15DAYS) {
4106			$time_format = 'M d H:i';
4107		}
4108		elseif ($period < SECONDS_1MONTH) {
4109			$time_format = 'M d H\h';
4110		}
4111		else {
4112			$time_format = 'M d H\h';
4113		}
4114
4115		$timestamp_short = date($time_format, $timestamp);
4116		$long_index[$timestamp_short] = date(
4117			html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp);
4118		$timestamp = $timestamp_short;
4119		/////////////////////////////////////////////////////////////////
4120
4121		// Data in the interval
4122		//The order in chart array is very important!!!!
4123		if ($show_events) {
4124			$chart[$timestamp]['event'] = $event_value;
4125		}
4126
4127		if ($show_alerts) {
4128			$chart[$timestamp]['alert'] = $alert_value;
4129		}
4130
4131		if (!$avg_only) {
4132			$chart[$timestamp]['max'] = 0;
4133		}
4134
4135		if ($count > 0) {
4136			$chart[$timestamp]['sum'] = $count;
4137		}
4138		else {
4139			// Compressed data
4140			$chart[$timestamp]['sum'] = $last_known;
4141		}
4142
4143		if (!$avg_only) {
4144			$chart[$timestamp]['min'] = 0;
4145		}
4146	}
4147
4148	$graph_stats = get_statwin_graph_statistics($chart);
4149
4150	// Fix event and alert scale
4151	$event_max = 2 + (float)$max_value * 1.05;
4152	foreach ($chart as $timestamp => $chart_data) {
4153		if (!empty($chart_data['event']) && $chart_data['event'] > 0) {
4154			$chart[$timestamp]['event'] = $event_max;
4155		}
4156		if (!empty($chart_data['alert']) && $chart_data['alert'] > 0) {
4157			$chart[$timestamp]['alert'] = $event_max;
4158		}
4159	}
4160
4161	if (empty($unit_name)) {
4162		$unit = modules_get_unit($agent_module_id);
4163	}
4164	else
4165		$unit = $unit_name;
4166
4167	/////////////////////////////////////////////////////////////////////////////////////////
4168	$color = array();
4169
4170	if ($show_events) {
4171		$color['event'] = array('border' => '#ff0000',
4172			'color' => '#ff0000', 'alpha' => CHART_DEFAULT_ALPHA);
4173	}
4174	if ($show_alerts) {
4175		$color['alert'] = array('border' => '#ff7f00',
4176			'color' => '#ff7f00', 'alpha' => CHART_DEFAULT_ALPHA);
4177	}
4178
4179	if (!$avg_only) {
4180		$color['max'] = array('border' => '#000000',
4181			'color' => $config['graph_color3'],
4182			'alpha' => CHART_DEFAULT_ALPHA);
4183	}
4184	$color['sum'] = array('border' => '#000000',
4185		'color' => $config['graph_color2'],
4186		'alpha' => CHART_DEFAULT_ALPHA);
4187
4188	if (!$avg_only) {
4189		$color['min'] = array('border' => '#000000',
4190			'color' => $config['graph_color1'],
4191			'alpha' => CHART_DEFAULT_ALPHA);
4192	}
4193
4194	//$color['baseline'] = array('border' => null, 'color' => '#0097BD', 'alpha' => 10);
4195	/////////////////////////////////////////////////////////////////////////////////////////
4196
4197	$flash_chart = $config['flash_charts'];
4198	if ($only_image) {
4199		$flash_chart = false;
4200	}
4201
4202	$legend = array();
4203
4204	if ($show_events) {
4205		$legend['event'] = __('Events');
4206	}
4207
4208	if ($show_alerts) {
4209		$legend['alert'] = __('Alerts');
4210	}
4211
4212	if (!$avg_only) {
4213		$legend['max'] = __('Max').': '.__('Last').': '.$graph_stats['max']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['max']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['max']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['max']['min'].' '.$unit;
4214	}
4215
4216	$legend['sum'] = __('Avg').': '.__('Last').': '.$graph_stats['sum']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['sum']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['sum']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['sum']['min'].' '.$unit;
4217
4218	if (!$avg_only) {
4219		$legend['min'] = __('Min').': '.__('Last').': '.$graph_stats['min']['last'].' '.$unit.' ; '.__('Avg').': '.$graph_stats['min']['avg'].' '.$unit.' ; '.__('Max').': '.$graph_stats['min']['max'].' '.$unit.' ; '.__('Min').': '.$graph_stats['min']['min'].' '.$unit;
4220	}
4221
4222	$water_mark = array('file' => $config['homedir'] .  "/images/logo_vertical_water.png",
4223		'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false));
4224
4225	if ($config['type_module_charts'] === 'area') {
4226		return area_graph($flash_chart, $chart, $width, $height, $color,
4227			$legend, array(), '', "", $unit, $homeurl,
4228			$water_mark, $config['fontpath'], $config['font_size'], $unit,
4229			1, array(),	array(), 0, 0, $adapt_key, true, '', $menu);
4230	}
4231	else {
4232		return
4233			line_graph($flash_chart, $chart, $width, $height, $color,
4234				$legend, $long_index,
4235				ui_get_full_url("images/image_problem.opaque.png", false, false, false),
4236				"", $unit, $water_mark, $config['fontpath'],
4237				$config['font_size'], $unit, $ttl, $homeurl, $backgroundColor);
4238	}
4239}
4240
4241/**
4242 * Print a graph with event data of module
4243 *
4244 * @param integer id_module Module ID
4245 * @param integer width graph width
4246 * @param integer height graph height
4247 * @param integer period time period
4248 * @param string homeurl Home url if the complete path is needed
4249 * @param int Zoom factor over the graph
4250 * @param string adaptation width and margin left key (could be adapter_[something] or adapted_[something])
4251 * @param int date limit of the period
4252 */
4253function graphic_module_events ($id_module, $width, $height, $period = 0, $homeurl = '', $zoom = 0, $adapt_key = '', $date = false, $stat_win = false) {
4254	global $config;
4255	global $graphic_type;
4256
4257	$data = array ();
4258
4259	$resolution = $config['graph_res'] * ($period * 2 / $width); // Number of "slices" we want in graph
4260
4261	$interval = (int) ($period / $resolution);
4262	if ($date === false) {
4263		$date = get_system_time ();
4264	}
4265	$datelimit = $date - $period;
4266	$periodtime = floor ($period / $interval);
4267	$time = array ();
4268	$data = array ();
4269
4270	// Set the title and time format
4271	if ($period <= SECONDS_6HOURS) {
4272		$time_format = 'H:i:s';
4273	}
4274	elseif ($period < SECONDS_1DAY) {
4275		$time_format = 'H:i';
4276	}
4277	elseif ($period < SECONDS_15DAYS) {
4278		$time_format = 'M d H:i';
4279	}
4280	elseif ($period < SECONDS_1MONTH) {
4281		$time_format = 'M d H\h';
4282	}
4283	else {
4284		$time_format = 'M d H\h';
4285	}
4286
4287	$legend = array();
4288	$cont = 0;
4289	for ($i = 0; $i < $interval; $i++) {
4290		$bottom = $datelimit + ($periodtime * $i);
4291		if (! $graphic_type) {
4292			$name = date($time_format, $bottom);
4293			//$name = date('H\h', $bottom);
4294		}
4295		else {
4296			$name = $bottom;
4297		}
4298
4299		$top = $datelimit + ($periodtime * ($i + 1));
4300
4301		$events = db_get_all_rows_filter ('tevento',
4302			array ('id_agentmodule' => $id_module,
4303				'utimestamp > '.$bottom,
4304				'utimestamp < '.$top),
4305			'event_type, utimestamp');
4306
4307		if (!empty($events)) {
4308			$status = 'normal';
4309			foreach($events as $event) {
4310				if (empty($event['utimestamp'])) {
4311					continue;
4312				}
4313
4314				switch($event['event_type']) {
4315					case 'going_down_normal':
4316					case 'going_up_normal':
4317						// The default status is normal. Do nothing
4318						break;
4319					case 'going_unknown':
4320						if ($status == 'normal') {
4321							$status = 'unknown';
4322						}
4323						break;
4324					case 'going_up_warning':
4325					case 'going_down_warning':
4326						if ($status == 'normal' || $status == 'unknown') {
4327							$status = 'warning';
4328						}
4329						break;
4330					case 'going_up_critical':
4331					case 'going_down_critical':
4332						$status = 'critical';
4333						break;
4334				}
4335			}
4336		}
4337
4338		$data[$cont]['utimestamp'] = $periodtime;
4339
4340		if (!empty($events)) {
4341			switch ($status) {
4342				case 'warning':
4343					$data[$cont]['data'] = 2;
4344					break;
4345				case 'critical':
4346					$data[$cont]['data'] = 3;
4347					break;
4348				case 'unknown':
4349					$data[$cont]['data'] = 4;
4350					break;
4351				default:
4352					$data[$cont]['data'] = 1;
4353					break;
4354			}
4355		}
4356		else {
4357			$data[$cont]['data'] = 1;
4358		}
4359		$current_timestamp = $bottom;
4360
4361		$legend[] = date($time_format, $current_timestamp);
4362		$cont++;
4363	}
4364
4365	$pixels_between_xdata = 25;
4366	$max_xdata_display = round($width / $pixels_between_xdata);
4367	$ndata = count($data);
4368	if ($max_xdata_display > $ndata) {
4369		$xdata_display = $ndata;
4370	}
4371	else {
4372		$xdata_display = $max_xdata_display;
4373	}
4374
4375	$step = round($ndata/$xdata_display);
4376
4377	$colors = array(1 => '#38B800', 2 => '#FFFF00', 3 => '#FF0000', 4 => '#C3C3C3');
4378
4379	// Draw slicebar graph
4380	if ($config['flash_charts']) {
4381		echo flot_slicesbar_graph($data, $period, $width, 15, $legend, $colors, $config['fontpath'], $config['round_corner'], $homeurl, '', $adapt_key, $stat_win);
4382	}
4383	else {
4384		echo slicesbar_graph($data, $period, $width, 15, $colors, $config['fontpath'], $config['round_corner'], $homeurl);
4385	}
4386}
4387
4388///Functions for the LOG4X graphs
4389function grafico_modulo_log4x ($id_agente_modulo, $periodo, $show_event,
4390	$width, $height , $title, $unit_name, $show_alert, $avg_only = 0, $pure=0,
4391	$date = 0) {
4392
4393	grafico_modulo_log4x_trace("<pre style='text-align:left;'>");
4394
4395	if ($date == "")
4396		$now = time ();
4397	else
4398		$now = $date;
4399
4400	$fechatope = $now - $periodo; // limit date
4401
4402	$nombre_agente = modules_get_agentmodule_agent_name ($id_agente_modulo);
4403	$nombre_modulo = modules_get_agentmodule_name ($id_agente_modulo);
4404	$id_agente = agents_get_agent_id ($nombre_agente);
4405
4406	$adjust_time = SECONDS_1MINUTE;
4407
4408
4409	if ($periodo == SECONDS_1DAY)
4410		$adjust_time = SECONDS_1HOUR;
4411	elseif ($periodo == SECONDS_1WEEK)
4412		$adjust_time = SECONDS_1DAY;
4413	elseif ($periodo == SECONDS_1HOUR)
4414		$adjust_time = SECONDS_10MINUTES;
4415	elseif ($periodo == SECONDS_1MONTH)
4416		$adjust_time = SECONDS_1WEEK;
4417	else
4418		$adjust_time = $periodo / 12.0;
4419
4420	$num_slices = $periodo / $adjust_time;
4421
4422	$fechatope_index = grafico_modulo_log4x_index($fechatope, $adjust_time);
4423
4424	$sql1="SELECT utimestamp, SEVERITY " .
4425			" FROM tagente_datos_log4x " .
4426			" WHERE id_agente_modulo = $id_agente_modulo AND utimestamp > $fechatope and utimestamp < $now";
4427
4428	$valores = array();
4429
4430	$max_count = -1;
4431	$min_count = 9999999;
4432
4433	grafico_modulo_log4x_trace("$sql1");
4434
4435	$rows = 0;
4436
4437	$first = true;
4438	while ($row = get_db_all_row_by_steps_sql($first, $result, $sql1)) {
4439		$first = false;
4440
4441		$rows++;
4442		$utimestamp = $row[0];
4443		$severity = $row[1];
4444		$severity_num = $row[2];
4445
4446		if (!isset($valores[$severity]))
4447			$valores[$severity] = array();
4448
4449		$dest = grafico_modulo_log4x_index($utimestamp, $adjust_time);
4450
4451		$index = (($dest - $fechatope_index) / $adjust_time) - 1;
4452
4453		if (!isset($valores[$severity][$index])) {
4454			$valores[$severity][$index] = array();
4455			$valores[$severity][$index]['pivot'] = $dest;
4456			$valores[$severity][$index]['count'] = 0;
4457			$valores[$severity][$index]['alerts'] = 0;
4458		}
4459
4460		$valores[$severity][$index]['count']++;
4461
4462		$max_count = max($max_count, $valores[$severity][$index]['count']);
4463		$min_count = min($min_count, $valores[$severity][$index]['count']);
4464	}
4465
4466	grafico_modulo_log4x_trace("$rows rows");
4467
4468	// Create graph
4469	// *************
4470
4471	grafico_modulo_log4x_trace(__LINE__);
4472
4473	//set_error_handler("myErrorHandler");
4474
4475	grafico_modulo_log4x_trace(__LINE__);
4476	$ds = DIRECTORY_SEPARATOR;
4477	set_include_path(get_include_path() . PATH_SEPARATOR . getcwd() . $ds."..".$ds."..".$ds."include");
4478
4479	require_once 'Image/Graph.php';
4480
4481	grafico_modulo_log4x_trace(__LINE__);
4482
4483	$Graph =& Image_Graph::factory('graph', array($width, $height));
4484
4485	grafico_modulo_log4x_trace(__LINE__);
4486
4487	// add a TrueType font
4488	$Font =& $Graph->addNew('font', $config['fontpath']); // C:\WINNT\Fonts\ARIAL.TTF
4489	$Font->setSize(7);
4490
4491	$Graph->setFont($Font);
4492
4493	if ($periodo == SECONDS_1DAY)
4494		$title_period = $lang_label["last_day"];
4495	elseif ($periodo == SECONDS_1WEEK)
4496		$title_period = $lang_label["last_week"];
4497	elseif ($periodo == SECONDS_1HOUR)
4498		$title_period = $lang_label["last_hour"];
4499	elseif ($periodo == SECONDS_1MONTH)
4500		$title_period = $lang_label["last_month"];
4501	else {
4502		$suffix = $lang_label["days"];
4503		$graph_extension = $periodo / SECONDS_1DAY;
4504
4505		if ($graph_extension < 1) {
4506			$graph_extension = $periodo / SECONDS_1HOUR;
4507			$suffix = $lang_label["hours"];
4508		}
4509		//$title_period = "Last ";
4510		$title_period = format_numeric($graph_extension,2)." $suffix";
4511	}
4512
4513	$title_period = html_entity_decode($title_period);
4514
4515	grafico_modulo_log4x_trace(__LINE__);
4516
4517	if ($pure == 0) {
4518		$Graph->add(
4519			Image_Graph::horizontal(
4520				Image_Graph::vertical(
4521					Image_Graph::vertical(
4522						$Title = Image_Graph::factory('title', array('   Pandora FMS Graph - '.strtoupper($nombre_agente)." - " .$title_period, 10)),
4523						$Subtitle = Image_Graph::factory('title', array('     '.$title, 7)),
4524						90
4525					),
4526					$Plotarea = Image_Graph::factory('plotarea', array('Image_Graph_Axis', 'Image_Graph_Axis')),
4527					15 // If you change this, change the 0.85 below
4528				),
4529				Image_Graph::vertical(
4530					$Legend = Image_Graph::factory('legend'),
4531					$PlotareaMinMax = Image_Graph::factory('plotarea'),
4532					65
4533				),
4534				85 // If you change this, change the 0.85 below
4535			)
4536		);
4537
4538		$Legend->setPlotarea($Plotarea);
4539		$Title->setAlignment(IMAGE_GRAPH_ALIGN_LEFT);
4540		$Subtitle->setAlignment(IMAGE_GRAPH_ALIGN_LEFT);
4541	}
4542	else { // Pure, without title and legends
4543		$Graph->add($Plotarea = Image_Graph::factory('plotarea', array('Image_Graph_Axis', 'Image_Graph_Axis')));
4544	}
4545
4546	grafico_modulo_log4x_trace(__LINE__);
4547
4548	$dataset = array();
4549
4550	$severities = array("FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE");
4551	$colors = array("black", "red", "orange", "yellow", "#3300ff", 'magenta');
4552
4553	$max_bubble_radius = $height * 0.6 / (count($severities) + 1); // this is the size for the max_count
4554	$y = count($severities) - 1;
4555	$i = 0;
4556
4557	foreach($severities as $severity) {
4558		$dataset[$i] = Image_Graph::factory('dataset');
4559		$dataset[$i]->setName($severity);
4560
4561		if (isset($valores[$severity])) {
4562			$data =& $valores[$severity];
4563			while (list($index, $data2) = each($data)) {
4564				$count = $data2['count'];
4565				$pivot = $data2['pivot'];
4566
4567				//$x = $scale * $index;
4568				$x = 100.0 * ($pivot - $fechatope) / ($now - $fechatope);
4569				if ($x > 100) $x = 100;
4570
4571				$size = grafico_modulo_log4x_bubble_size($count, $max_count, $max_bubble_radius);
4572
4573				// pivot is the value in the X axis
4574				// y is the number of steps (from the bottom of the graphics) (zero based)
4575				// x is the position of the bubble, in % from the left (0% = full left, 100% = full right)
4576				// size is the radius of the bubble
4577				// value is the value associated with the bubble (needed to calculate the leyend)
4578				//
4579				$dataset[$i]->addPoint($pivot, $y, array("x" => $x, "size" => $size, "value" => $count));
4580			}
4581		}
4582		else {
4583			// There's a problem when we have no data ...
4584			// This was the first try.. didnt work
4585			//$dataset[$i]->addPoint($now, -1, array("x" => 0, "size" => 0));
4586		}
4587
4588		$y--;
4589		$i++;
4590	}
4591
4592	grafico_modulo_log4x_trace(__LINE__);
4593
4594	// create the 1st plot as smoothed area chart using the 1st dataset
4595	$Plot =& $Plotarea->addNew('bubble', array(&$dataset));
4596	$Plot->setFont($Font);
4597
4598	$AxisX =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_X);
4599	$AxisX->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', 'grafico_modulo_log4x_format_x_axis'));
4600	$AxisX->forceMinimum($fechatope);
4601	$AxisX->forceMaximum($now);
4602
4603	$minIntervalWidth = $Plot->getTextWidth("88/88/8888");
4604	$interval_x = $adjust_time;
4605
4606	while (true) {
4607		$intervalWidth = $width * 0.85 * $interval_x/ $periodo;
4608		if ($intervalWidth >= $minIntervalWidth)
4609			break;
4610
4611		$interval_x *= 2;
4612	}
4613
4614	$AxisX->setLabelInterval($interval_x);
4615	$AxisX->setLabelOption("showtext",true);
4616
4617	//*
4618	$GridY2 =& $Plotarea->addNew('line_grid');
4619	$GridY2->setLineColor('gray');
4620	$GridY2->setFillColor('lightgray@0.05');
4621	$GridY2->_setPrimaryAxis($AxisX);
4622	//$GridY2->setLineStyle(Image_Graph::factory('Image_Graph_Line_Dotted', array("white", "gray", "gray", "gray")));
4623	$GridY2->setLineStyle(Image_Graph::factory('Image_Graph_Line_Formatted', array(array("transparent", "transparent", "transparent", "gray"))));
4624	//*/
4625	//grafico_modulo_log4x_trace(print_r($AxisX, true));
4626
4627	$AxisY =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
4628	$AxisY->setDataPreprocessor(Image_Graph::factory('Image_Graph_DataPreprocessor_Function', 'grafico_modulo_log4x_format_y_axis'));
4629	$AxisY->setLabelOption("showtext",true);
4630	//$AxisY->setLabelInterval(0);
4631	//$AxisY->showLabel(IMAGE_GRAPH_LABEL_ZERO);
4632
4633	//*
4634	$GridY2 =& $Plotarea->addNew('line_grid');
4635	$GridY2->setLineColor('gray');
4636	$GridY2->setFillColor('lightgray@0.05');
4637	$GridY2->_setPrimaryAxis($AxisY);
4638	$GridY2->setLineStyle(Image_Graph::factory('Image_Graph_Line_Formatted', array(array("transparent", "transparent", "transparent", "gray"))));
4639	//*/
4640
4641	$AxisY->forceMinimum(0);
4642	$AxisY->forceMaximum(count($severities) + 1) ;
4643
4644	// set line colors
4645	$FillArray =& Image_Graph::factory('Image_Graph_Fill_Array');
4646
4647	$Plot->setFillStyle($FillArray);
4648	foreach($colors as $color)
4649		$FillArray->addColor($color);
4650
4651	grafico_modulo_log4x_trace(__LINE__);
4652
4653	$FillArray->addColor('green@0.6');
4654	//$AxisY_Weather =& $Plotarea->getAxis(IMAGE_GRAPH_AXIS_Y);
4655
4656	// Show events !
4657	if ($show_event == 1) {
4658		$Plot =& $Plotarea->addNew('Plot_Impulse', array($dataset_event));
4659		$Plot->setLineColor( 'red' );
4660		$Marker_event =& Image_Graph::factory('Image_Graph_Marker_Cross');
4661		$Plot->setMarker($Marker_event);
4662		$Marker_event->setFillColor( 'red' );
4663		$Marker_event->setLineColor( 'red' );
4664		$Marker_event->setSize ( 5 );
4665	}
4666
4667	$Axis =& $PlotareaMinMax->getAxis(IMAGE_GRAPH_AXIS_X);
4668	$Axis->Hide();
4669	$Axis =& $PlotareaMinMax->getAxis(IMAGE_GRAPH_AXIS_Y);
4670	$Axis->Hide();
4671
4672	$plotMinMax =& $PlotareaMinMax->addNew('bubble', array(&$dataset, true));
4673
4674	grafico_modulo_log4x_trace(__LINE__);
4675
4676	$Graph->done();
4677
4678	grafico_modulo_log4x_trace(__LINE__);
4679}
4680
4681function grafico_modulo_log4x_index($x, $interval)
4682{
4683	return $x + $interval - (($x - 1) % $interval) - 1;
4684}
4685
4686function grafico_modulo_log4x_trace($str)
4687{
4688	//echo "$str\n";
4689}
4690
4691function grafico_modulo_log4x_bubble_size($count, $max_count, $max_bubble_radius)
4692{
4693	//Superformula de ROA
4694	$r0 = 1.5;
4695	$r1 = $max_bubble_radius;
4696	$v2 = pow($max_count,1/2.0);
4697
4698	return $r1*pow($count,1/2.0)/($v2)+$r0;
4699}
4700
4701function grafico_modulo_log4x_format_x_axis ( $number , $decimals=2, $dec_point=".", $thousands_sep=",")
4702{
4703	// $number is the unix time in the local timezone
4704
4705	//$dtZone = new DateTimeZone(date_default_timezone_get());
4706	//$d = new DateTime("now", $dtZone);
4707	//$offset = $dtZone->getOffset($d);
4708	//$number -= $offset;
4709
4710	return date("d/m", $number) . "\n" . date("H:i", $number);
4711}
4712
4713function grafico_modulo_log4x_format_y_axis ( $number , $decimals=2, $dec_point=".", $thousands_sep=",")
4714{
4715
4716	switch ($number) {
4717		case 6:
4718			return "FATAL";
4719			break;
4720		case 5:
4721			return "ERROR";
4722			break;
4723		case 4:
4724			return "WARN";
4725			break;
4726		case 3:
4727			return "INFO";
4728			break;
4729		case 2:
4730			return "DEBUG";
4731			break;
4732		case 1:
4733			return "TRACE";
4734			break;
4735		default:
4736			return "";
4737			break;
4738	}
4739
4740}
4741
4742function graph_nodata_image($width = 300, $height = 110, $type = 'area', $text = '') {
4743	$image = ui_get_full_url('images/image_problem_' . $type . '.png',
4744		false, false, false);
4745
4746	if ($text == '') {
4747		$text = __('No data to show');
4748	}
4749
4750	$text_div = '<div class="nodata_text">' . $text . '</div>';
4751
4752	$image_div = '<div class="nodata_container" style="background-image: url(\'' . $image . '\');">' .
4753		$text_div . '</div>';
4754
4755	$div = '<div style="width:' . $width . 'px; height:' . $height . 'px; border: 1px dotted #ddd; background-color: white; margin: 0 auto;">' .
4756		$image_div . '</div>';
4757
4758	return $div;
4759}
4760
4761function get_criticity_pie_colors ($data_graph) {
4762	$colors = array();
4763	foreach (array_keys($data_graph) as $crit) {
4764		switch ($crit) {
4765			case __('Maintenance'):
4766				$colors[$crit] = COL_MAINTENANCE;
4767				break;
4768			case __('Informational'):
4769				$colors[$crit] = COL_INFORMATIONAL;
4770				break;
4771			case __('Normal'):
4772				$colors[$crit] = COL_NORMAL;
4773				break;
4774			case __('Warning'):
4775				$colors[$crit] = COL_WARNING;
4776				break;
4777			case __('Critical'):
4778				$colors[$crit] = COL_CRITICAL;
4779				break;
4780			case __('Minor'):
4781				$colors[$crit] = COL_MINOR;
4782				break;
4783			case __('Major'):
4784				$colors[$crit] = COL_MAJOR;
4785				break;
4786		}
4787	}
4788
4789	return $colors;
4790}
4791
4792
4793/**
4794 * Print a rectangular graph with the snmptraps received
4795 */
4796function graph_snmp_traps_treemap ($data, $width = 700, $height = 700) {
4797	global $config;
4798
4799	if (empty ($data)) {
4800		return fs_error_image ();
4801	}
4802
4803	include_once($config['homedir'] . "/include/graphs/functions_d3.php");
4804
4805	return d3_tree_map_graph ($data, $width, $height, true);
4806}
4807
4808/**
4809 * Print a solarburst graph with a representation of all the groups, agents, module groups and modules grouped
4810 */
4811function graph_monitor_wheel ($width = 550, $height = 600, $filter = false) {
4812	global $config;
4813
4814	include_once ($config['homedir'] . "/include/functions_users.php");
4815	include_once ($config['homedir'] . "/include/functions_groups.php");
4816	include_once ($config['homedir'] . "/include/functions_agents.php");
4817	include_once ($config['homedir'] . "/include/functions_modules.php");
4818
4819	$graph_data = array();
4820
4821	$filter_module_group = (!empty($filter) && !empty($filter['module_group'])) ? $filter['module_group'] : false;
4822
4823	$groups = users_get_groups(false, "AR", false, true, (!empty($filter) && isset($filter['group']) ? $filter['group'] : null));
4824
4825	$data_groups = array();
4826	if (!empty($groups)) {
4827		$groups_aux = $groups;
4828		$data_groups = groups_get_tree($groups);
4829		$groups_aux = null;
4830	}
4831
4832	if (!empty($data_groups)) {
4833		$filter = array('id_grupo' => array_keys($groups));
4834		$fields = array('id_agente', 'id_parent', 'id_grupo', 'nombre');
4835		$agents = agents_get_agents($filter, $fields);
4836
4837		if (!empty($agents)) {
4838			$agents_id = array();
4839			$agents_aux = array();
4840			foreach ($agents as $key => $agent) {
4841				$agents_aux[$agent['id_agente']] = $agent;
4842			}
4843			$agents = $agents_aux;
4844			$agents_aux = null;
4845			$fields = array('id_agente_modulo', 'id_agente', 'id_module_group', 'nombre');
4846
4847			$module_groups = modules_get_modulegroups();
4848			$module_groups[0] = __('Not assigned');
4849			$modules = agents_get_modules(array_keys($agents), '*');
4850
4851			$data_agents = array();
4852			if (!empty($modules)) {
4853				foreach ($modules as $key => $module) {
4854					$module_id = (int) $module['id_agente_modulo'];
4855					$agent_id = (int) $module['id_agente'];
4856					$module_group_id = (int) $module['id_module_group'];
4857					$module_name = io_safe_output($module['nombre']);
4858					$module_status = modules_get_agentmodule_status($module_id);
4859					$module_value = modules_get_last_value($module_id);
4860
4861					if ($filter_module_group && $filter_module_group != $module_group_id)
4862						continue;
4863
4864					if (!isset($data_agents[$agent_id])) {
4865						$data_agents[$agent_id] = array();
4866						$data_agents[$agent_id]['id'] = $agent_id;
4867						$data_agents[$agent_id]['name'] = io_safe_output($agents[$agent_id]['nombre']);
4868						$data_agents[$agent_id]['group'] = (int) $agents[$agent_id]['id_grupo'];
4869						$data_agents[$agent_id]['type'] = 'agent';
4870						$data_agents[$agent_id]['size'] = 30;
4871						$data_agents[$agent_id]['children'] = array();
4872
4873						$tooltip_content = __('Agent') . ": <b>" . $data_agents[$agent_id]['name'] . "</b>";
4874						$data_agents[$agent_id]['tooltip_content'] = io_safe_output($tooltip_content);
4875
4876						$data_agents[$agent_id]['modules_critical'] = 0;
4877						$data_agents[$agent_id]['modules_warning'] = 0;
4878						$data_agents[$agent_id]['modules_normal'] = 0;
4879						$data_agents[$agent_id]['modules_not_init'] = 0;
4880						$data_agents[$agent_id]['modules_not_normal'] = 0;
4881						$data_agents[$agent_id]['modules_unknown'] = 0;
4882
4883						$data_agents[$agent_id]['color'] = COL_UNKNOWN;
4884
4885						unset($agents[$agent_id]);
4886					}
4887					if (!isset($data_agents[$agent_id]['children'][$module_group_id])) {
4888						$data_agents[$agent_id]['children'][$module_group_id] = array();
4889						$data_agents[$agent_id]['children'][$module_group_id]['id'] = $module_group_id;
4890						$data_agents[$agent_id]['children'][$module_group_id]['name'] = io_safe_output($module_groups[$module_group_id]);
4891						$data_agents[$agent_id]['children'][$module_group_id]['type'] = 'module_group';
4892						$data_agents[$agent_id]['children'][$module_group_id]['size'] = 10;
4893						$data_agents[$agent_id]['children'][$module_group_id]['children'] = array();
4894
4895						$tooltip_content = __('Module group') . ": <b>" . $data_agents[$agent_id]['children'][$module_group_id]['name'] . "</b>";
4896						$data_agents[$agent_id]['children'][$module_group_id]['tooltip_content'] = $tooltip_content;
4897
4898						$data_agents[$agent_id]['children'][$module_group_id]['modules_critical'] = 0;
4899						$data_agents[$agent_id]['children'][$module_group_id]['modules_warning'] = 0;
4900						$data_agents[$agent_id]['children'][$module_group_id]['modules_normal'] = 0;
4901						$data_agents[$agent_id]['children'][$module_group_id]['modules_not_init'] = 0;
4902						$data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal'] = 0;
4903						$data_agents[$agent_id]['children'][$module_group_id]['modules_unknown'] = 0;
4904
4905						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_UNKNOWN;
4906					}
4907
4908					switch ($module_status) {
4909						case AGENT_MODULE_STATUS_CRITICAL_BAD:
4910						case AGENT_MODULE_STATUS_CRITICAL_ALERT:
4911							$data_agents[$agent_id]['modules_critical']++;
4912							$data_agents[$agent_id]['children'][$module_group_id]['modules_critical']++;
4913							break;
4914
4915						case AGENT_MODULE_STATUS_WARNING:
4916						case AGENT_MODULE_STATUS_WARNING_ALERT:
4917							$data_agents[$agent_id]['modules_warning']++;
4918							$data_agents[$agent_id]['children'][$module_group_id]['modules_warning']++;
4919							break;
4920
4921						case AGENT_MODULE_STATUS_NORMAL:
4922						case AGENT_MODULE_STATUS_NORMAL_ALERT:
4923							$data_agents[$agent_id]['modules_normal']++;
4924							$data_agents[$agent_id]['children'][$module_group_id]['modules_normal']++;
4925							break;
4926
4927						case AGENT_MODULE_STATUS_NOT_INIT:
4928							$data_agents[$agent_id]['modules_not_init']++;
4929							$data_agents[$agent_id]['children'][$module_group_id]['modules_not_init']++;
4930							break;
4931
4932						case AGENT_MODULE_STATUS_NOT_NORMAL:
4933							$data_agents[$agent_id]['modules_not_normal']++;
4934							$data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal']++;
4935							break;
4936
4937						case AGENT_MODULE_STATUS_NO_DATA:
4938						case AGENT_MODULE_STATUS_UNKNOWN:
4939							$data_agents[$agent_id]['modules_unknown']++;
4940							$data_agents[$agent_id]['children'][$module_group_id]['modules_unknown']++;
4941							break;
4942					}
4943
4944					if ($data_agents[$agent_id]['modules_critical'] > 0) {
4945						$data_agents[$agent_id]['color'] = COL_CRITICAL;
4946					}
4947					else if ($data_agents[$agent_id]['modules_warning'] > 0) {
4948						$data_agents[$agent_id]['color'] = COL_WARNING;
4949					}
4950					else if ($data_agents[$agent_id]['modules_not_normal'] > 0) {
4951						$data_agents[$agent_id]['color'] = COL_WARNING;
4952					}
4953					else if ($data_agents[$agent_id]['modules_unknown'] > 0) {
4954						$data_agents[$agent_id]['color'] = COL_UNKNOWN;
4955					}
4956					else if ($data_agents[$agent_id]['modules_normal'] > 0) {
4957						$data_agents[$agent_id]['color'] = COL_NORMAL;
4958					}
4959					else {
4960						$data_agents[$agent_id]['color'] = COL_NOTINIT;
4961					}
4962
4963					if ($data_agents[$agent_id]['children'][$module_group_id]['modules_critical'] > 0) {
4964						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_CRITICAL;
4965					}
4966					else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_warning'] > 0) {
4967						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_WARNING;
4968					}
4969					else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_not_normal'] > 0) {
4970						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_WARNING;
4971					}
4972					else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_unknown'] > 0) {
4973						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_UNKNOWN;
4974					}
4975					else if ($data_agents[$agent_id]['children'][$module_group_id]['modules_normal'] > 0) {
4976						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_NORMAL;
4977					}
4978					else {
4979						$data_agents[$agent_id]['children'][$module_group_id]['color'] = COL_NOTINIT;
4980					}
4981
4982					$data_module = array();
4983					$data_module['id'] = $module_id;
4984					$data_module['name'] = $module_name;
4985					$data_module['type'] = 'module';
4986					$data_module['size'] = 10;
4987					$data_module['link'] = ui_get_full_url("index.php?sec=estado&sec2=operation/agentes/ver_agente&id_agente=$agent_id");
4988
4989					$tooltip_content = __('Module') . ": <b>" . $module_name . "</b>";
4990					if (isset($module_value) && $module_value !== false) {
4991						$tooltip_content .= "<br>";
4992						$tooltip_content .= __('Value') . ": <b>" . io_safe_output($module_value) . "</b>";
4993					}
4994					$data_module['tooltip_content'] = $tooltip_content;
4995
4996					switch ($module_status) {
4997						case AGENT_MODULE_STATUS_CRITICAL_BAD:
4998						case AGENT_MODULE_STATUS_CRITICAL_ALERT:
4999							$data_module['color'] = COL_CRITICAL;
5000							break;
5001
5002						case AGENT_MODULE_STATUS_WARNING:
5003						case AGENT_MODULE_STATUS_WARNING_ALERT:
5004							$data_module['color'] = COL_WARNING;
5005							break;
5006
5007						case AGENT_MODULE_STATUS_NORMAL:
5008						case AGENT_MODULE_STATUS_NORMAL_ALERT:
5009							$data_module['color'] = COL_NORMAL;
5010							break;
5011
5012						case AGENT_MODULE_STATUS_NOT_INIT:
5013							$data_module['color'] = COL_NOTINIT;
5014							break;
5015
5016						case AGENT_MODULE_STATUS_NOT_NORMAL:
5017							$data_module['color'] = COL_WARNING;
5018							break;
5019
5020						case AGENT_MODULE_STATUS_NO_DATA:
5021						case AGENT_MODULE_STATUS_UNKNOWN:
5022						default:
5023							$data_module['color'] = COL_UNKNOWN;
5024							break;
5025					}
5026
5027					$data_agents[$agent_id]['children'][$module_group_id]['children'][] = $data_module;
5028					unset($modules[$module_id]);
5029				}
5030				function order_module_group_keys ($value, $key) {
5031					$value['children'] = array_merge($value['children']);
5032					return $value;
5033				}
5034				$data_agents = array_map('order_module_group_keys', $data_agents);
5035			}
5036			foreach ($agents as $id => $agent) {
5037				if (!isset($data_agents[$id])) {
5038					$data_agents[$id] = array();
5039					$data_agents[$id]['id'] = (int) $id;
5040					$data_agents[$id]['name'] = io_safe_output($agent['nombre']);
5041					$data_agents[$id]['type'] = 'agent';
5042					$data_agents[$id]['color'] = COL_NOTINIT;
5043				}
5044			}
5045			$agents = null;
5046		}
5047	}
5048
5049	function iterate_group_array ($groups, &$data_agents) {
5050
5051		$data = array();
5052
5053		foreach ($groups as $id => $group) {
5054
5055			$group_aux = array();
5056			$group_aux['id'] = (int) $id;
5057			$group_aux['name'] = io_safe_output($group['nombre']);
5058			$group_aux['show_name'] = true;
5059			$group_aux['parent'] = (int) $group['parent'];
5060			$group_aux['type'] = 'group';
5061			$group_aux['size'] = 100;
5062			$group_aux['status'] = groups_get_status($id);
5063
5064			switch ($group_aux['status']) {
5065				case AGENT_STATUS_CRITICAL:
5066					$group_aux['color'] = COL_CRITICAL;
5067					break;
5068
5069				case AGENT_STATUS_WARNING:
5070				case AGENT_STATUS_ALERT_FIRED:
5071					$group_aux['color'] = COL_WARNING;
5072					break;
5073
5074				case AGENT_STATUS_NORMAL:
5075					$group_aux['color'] = COL_NORMAL;
5076					break;
5077
5078				case AGENT_STATUS_UNKNOWN:
5079				default:
5080					$group_aux['color'] = COL_UNKNOWN;
5081					break;
5082			}
5083
5084			$tooltip_content = html_print_image("images/groups_small/" . $group['icon'] . ".png", true) . "&nbsp;" . __('Group') . ": <b>" . $group_aux['name'] . "</b>";
5085			$group_aux['tooltip_content'] = $tooltip_content;
5086
5087			if (!isset($group['children']))
5088				$group_aux['children'] = array();
5089			if (!empty($group['children']))
5090				$group_aux['children'] = iterate_group_array($group['children'], $data_agents);
5091
5092			$agents = extract_agents_with_group_id($data_agents, (int) $id);
5093
5094			if (!empty($agents))
5095				$group_aux['children'] = array_merge($group_aux['children'], $agents);
5096
5097			$data[] = $group_aux;
5098		}
5099
5100		return $data;
5101	}
5102
5103	function extract_agents_with_group_id (&$agents, $group_id) {
5104		$valid_agents = array();
5105		foreach ($agents as $id => $agent) {
5106			if (isset($agent['group']) && $agent['group'] == $group_id) {
5107				$valid_agents[$id] = $agent;
5108				unset($agents[$id]);
5109			}
5110		}
5111		if (!empty($valid_agents))
5112			return $valid_agents;
5113		else
5114			return false;
5115	}
5116
5117	$graph_data = array('name' => __('Main node'), 'children' => iterate_group_array($data_groups, $data_agents), 'color' => '#3F3F3F');
5118
5119	if (empty($graph_data['children']))
5120		return fs_error_image();
5121
5122	include_once($config['homedir'] . "/include/graphs/functions_d3.php");
5123
5124	return d3_sunburst_graph ($graph_data, $width, $height, true);
5125}
5126
5127?>
5128