2013-02-19 Miguel de Dios <miguel.dedios@artica.es>

* include/functions_api.php, include/functions_agents.php,
	include/functions_config.php, include/ajax/reporting.ajax.php,
	include/functions_snmp_browser.php,
	operation/agentes/status_monitor.php: improved code style.
	
	* include/functions_graph.php, include/graphs/fgraph.php,
	include/graphs/flot/jquery.flot.pie.js,
	include/graphs/flot/jquery.flot.pie.min.js,
	include/graphs/flot/pandora.flot.js,
	include/graphs/functions_flot.php: fixed the pie graphs, added the
	expanded version of flot pie js file with some changes for the
	last version of jQuery.
	
	Fixes: #3604555




git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@7675 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
mdtrooper 2013-02-19 10:35:04 +00:00
parent 62f52054f7
commit 5a25f43ead
13 changed files with 1131 additions and 304 deletions

View File

@ -1,3 +1,20 @@
2013-02-19 Miguel de Dios <miguel.dedios@artica.es>
* include/functions_api.php, include/functions_agents.php,
include/functions_config.php, include/ajax/reporting.ajax.php,
include/functions_snmp_browser.php,
operation/agentes/status_monitor.php: improved code style.
* include/functions_graph.php, include/graphs/fgraph.php,
include/graphs/flot/jquery.flot.pie.js,
include/graphs/flot/jquery.flot.pie.min.js,
include/graphs/flot/pandora.flot.js,
include/graphs/functions_flot.php: fixed the pie graphs, added the
expanded version of flot pie js file with some changes for the
last version of jQuery.
Fixes: #3604555
2013-02-18 Sergio Martin <sergio.martin@artica.es>
* include/functions_html.php

View File

@ -1847,7 +1847,8 @@ function agents_get_count_incidents ($id_agent) {
return false;
}
return db_get_value('count(*)', 'tincidencia', 'id_agent', $id_agent);
return db_get_value('count(*)', 'tincidencia', 'id_agent',
$id_agent);
}
/**
@ -1864,7 +1865,9 @@ function agents_monitor_critical ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT critical_count FROM tagente WHERE id_agente = $id_agent" . $filter);
return db_get_sql ("SELECT critical_count
FROM tagente
WHERE id_agente = $id_agent" . $filter);
}
// Get warning monitors by using the status code in modules.
@ -1875,7 +1878,9 @@ function agents_monitor_warning ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT warning_count FROM tagente WHERE id_agente = $id_agent" . $filter);
return db_get_sql ("SELECT warning_count
FROM tagente
WHERE id_agente = $id_agent" . $filter);
}
// Get unknown monitors by using the status code in modules.
@ -1886,7 +1891,9 @@ function agents_monitor_unknown ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT unknown_count FROM tagente WHERE id_agente = $id_agent" . $filter);
return db_get_sql ("SELECT unknown_count
FROM tagente
WHERE id_agente = $id_agent" . $filter);
}
// Get ok monitors by using the status code in modules.
@ -1896,7 +1903,9 @@ function agents_monitor_ok ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT normal_count FROM tagente WHERE id_agente = $id_agent" . $filter);
return db_get_sql ("SELECT normal_count
FROM tagente
WHERE id_agente = $id_agent" . $filter);
}
/**
@ -1913,7 +1922,12 @@ function agents_monitor_disabled ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT COUNT( DISTINCT tagente_modulo.id_agente_modulo) FROM tagente, tagente_modulo WHERE tagente_modulo.id_agente = tagente.id_agente AND tagente_modulo.disabled = 1 AND tagente.id_agente = $id_agent".$filter);
return db_get_sql("
SELECT COUNT( DISTINCT tagente_modulo.id_agente_modulo)
FROM tagente, tagente_modulo
WHERE tagente_modulo.id_agente = tagente.id_agente
AND tagente_modulo.disabled = 1
AND tagente.id_agente = $id_agent".$filter);
}
/**
@ -1930,7 +1944,9 @@ function agents_monitor_notinit ($id_agent, $filter="") {
$filter = " AND ".$filter;
}
return db_get_sql ("SELECT notinit_count FROM tagente WHERE id_agente = $id_agent" . $filter);
return db_get_sql ("SELECT notinit_count
FROM tagente
WHERE id_agente = $id_agent" . $filter);
}
/**

View File

@ -2122,7 +2122,8 @@ function api_set_create_alert_template($name, $thrash1, $other, $thrash3) {
'priority' => $other['data'][25],
'id_group' => $other['data'][26]
);
} else {
}
else {
$values = array(
'description' => $other['data'][1],
'field1' => $other['data'][3],
@ -2183,21 +2184,26 @@ function api_set_create_alert_template($name, $thrash1, $other, $thrash3) {
function api_set_update_alert_template($id_template, $thrash1, $other, $thrash3) {
if ($id_template == "") {
returnError('error_update_alert_template', __('Error updating alert template. Id_template cannot be left blank.'));
returnError('error_update_alert_template',
__('Error updating alert template. Id_template cannot be left blank.'));
return;
}
$result_template = alerts_get_alert_template_name($id_template);
if (!$result_template) {
returnError('error_update_alert_template', __('Error updating alert template. Id_template doesn\'t exists.'));
returnError('error_update_alert_template',
__('Error updating alert template. Id_template doesn\'t exists.'));
return;
}
$fields_template = array('name', 'type', 'description', 'id_alert_action', 'field1', 'field2', 'field3', 'value', 'matches_value',
'max_value', 'min_value', 'time_threshold', 'max_alerts', 'min_alerts', 'time_from', 'time_to',
'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday', 'recovery_notify',
'field2_recovery', 'field3_recovery', 'priority', 'id_group');
$fields_template = array('name', 'type', 'description',
'id_alert_action', 'field1', 'field2', 'field3', 'value',
'matches_value', 'max_value', 'min_value', 'time_threshold',
'max_alerts', 'min_alerts', 'time_from', 'time_to', 'monday',
'tuesday', 'wednesday', 'thursday', 'friday', 'saturday',
'sunday', 'recovery_notify', 'field2_recovery',
'field3_recovery', 'priority', 'id_group');
$cont = 0;
foreach ($fields_template as $field) {
@ -2212,10 +2218,13 @@ function api_set_update_alert_template($id_template, $thrash1, $other, $thrash3)
if (is_error($id_template)) {
// TODO: Improve the error returning more info
returnError('error_create_alert_template', __('Error updating alert template.'));
returnError('error_create_alert_template',
__('Error updating alert template.'));
}
else {
returnData('string', array('type' => 'string', 'data' => __('Correct updating of alert template')));
returnData('string',
array('type' => 'string',
'data' => __('Correct updating of alert template')));
}
}
@ -2235,7 +2244,8 @@ function api_set_update_alert_template($id_template, $thrash1, $other, $thrash3)
function api_set_delete_alert_template($id_template, $thrash1, $other, $thrash3) {
if ($id_template == "") {
returnError('error_delete_alert_template', __('Error deleting alert template. Id_template cannot be left blank.'));
returnError('error_delete_alert_template',
__('Error deleting alert template. Id_template cannot be left blank.'));
return;
}
@ -2243,10 +2253,12 @@ function api_set_delete_alert_template($id_template, $thrash1, $other, $thrash3)
if ($result == 0) {
// TODO: Improve the error returning more info
returnError('error_create_alert_template', __('Error deleting alert template.'));
returnError('error_create_alert_template',
__('Error deleting alert template.'));
}
else {
returnData('string', array('type' => 'string', 'data' => __('Correct deleting of alert template.')));
returnData('string', array('type' => 'string',
'data' => __('Correct deleting of alert template.')));
}
}
@ -2279,7 +2291,8 @@ function api_get_all_alert_templates($thrash1, $thrash2, $other, $thrash3) {
}
if (!$template) {
returnError('error_get_all_alert_templates', __('Error getting all alert templates.'));
returnError('error_get_all_alert_templates',
__('Error getting all alert templates.'));
}
else {
returnData('csv', $data, $separator);
@ -2307,14 +2320,16 @@ function api_get_alert_template($id_template, $thrash1, $other, $thrash3) {
$result_template = alerts_get_alert_template_name($id_template);
if (!$result_template){
returnError('error_get_alert_template', __('Error getting alert template. Id_template doesn\'t exists.'));
returnError('error_get_alert_template',
__('Error getting alert template. Id_template doesn\'t exists.'));
return;
}
$filter_templates = array('id' => $id_template);
}
$template = alerts_get_alert_templates($filter_templates, array('id', 'name', 'description', 'id_alert_action', 'type', 'id_group'));
$template = alerts_get_alert_templates($filter_templates,
array('id', 'name', 'description', 'id_alert_action', 'type', 'id_group'));
if ($template !== false) {
$data['type'] = 'array';
@ -2322,7 +2337,8 @@ function api_get_alert_template($id_template, $thrash1, $other, $thrash3) {
}
if (!$template) {
returnError('error_get_alert_template', __('Error getting alert template.'));
returnError('error_get_alert_template',
__('Error getting alert template.'));
}
else {
returnData('csv', $data, ';');

View File

@ -1892,9 +1892,12 @@ function graph_events_validated($width = 300, $height = 200, $url = "", $meta =
$data_graph = reporting_get_count_events_validated(
array('id_group' => array_keys(users_get_groups())));
$water_mark = array('file' => $config['homedir'] . "/images/logo_vertical_water.png",
'url' => ui_get_full_url("images/logo_vertical_water.png", false, false, false, false));
echo pie3d_graph(
true, $data_graph, $width, $height, __("other"), "",
$config['homedir'] . "/images/logo_vertical_water.png",
$water_mark,
$config['fontpath'], $config['font_size']);
}
@ -2065,7 +2068,8 @@ function grafico_eventos_total($filter = "") {
asort ($data);
$water_mark = array('file' => $config['homedir'] . "/images/logo_vertical_water.png",
$water_mark = array(
'file' => $config['homedir'] . "/images/logo_vertical_water.png",
'url' => ui_get_full_url("/images/logo_vertical_water.png"));
return pie3d_graph($config['flash_charts'], $data, 320, 200,
@ -2094,10 +2098,12 @@ function grafico_eventos_usuario ($width, $height) {
ORDER BY 1 DESC LIMIT %d', $max_items);
break;
case "oracle":
$sql = sprintf ('SELECT * FROM (SELECT COUNT(id_evento) events, id_usuario
$sql = sprintf ('SELECT *
FROM (SELECT COUNT(id_evento) events, id_usuario
FROM tevento
GROUP BY id_usuario
ORDER BY 1 DESC) WHERE rownum <= %d', $max_items);
ORDER BY 1 DESC)
WHERE rownum <= %d', $max_items);
break;
}
$events = db_get_all_rows_sql ($sql);
@ -2110,12 +2116,16 @@ function grafico_eventos_usuario ($width, $height) {
if ($event['id_usuario'] == '0') {
$data[__('System')] = $event['events'];
}
elseif ($event['id_usuario'] == '') {
$data[__('System')] = $event['events'];
}
else {
$data[$event['id_usuario']] = $event['events'];
}
}
$water_mark = array('file' => $config['homedir'] . "/images/logo_vertical_water.png",
$water_mark = array(
'file' => $config['homedir'] . "/images/logo_vertical_water.png",
'url' => ui_get_full_url("/images/logo_vertical_water.png"));
return pie3d_graph($config['flash_charts'], $data, $width, $height,

View File

@ -44,7 +44,8 @@ function snmp_browser_print_tree ($tree, $id = 0, $depth = 0, $last = 0, $last_a
if ($depth > 0) {
echo "<ul id='ul_$id' style='margin: 0; padding: 0; display: none'>\n";
} else {
}
else {
echo "<ul id='ul_$id' style='margin: 0; padding: 0;'>\n";
}
foreach ($tree['__LEAVES__'] as $level => $sub_level) {
@ -70,12 +71,15 @@ function snmp_browser_print_tree ($tree, $id = 0, $depth = 0, $last = 0, $last_a
if ($depth == 0 && $count == 0) {
if ($count == $total) {
html_print_image ("operation/tree/one_closed.png", false, array ("style" => 'vertical-align: middle;'));
} else {
}
else {
html_print_image ("operation/tree/first_closed.png", false, array ("style" => 'vertical-align: middle;'));
}
} else if ($count == $total) {
}
else if ($count == $total) {
html_print_image ("operation/tree/last_closed.png", false, array ("style" => 'vertical-align: middle;'));
} else {
}
else {
html_print_image ("operation/tree/closed.png", false, array ("style" => 'vertical-align: middle;'));
}
echo "</a>";
@ -85,12 +89,15 @@ function snmp_browser_print_tree ($tree, $id = 0, $depth = 0, $last = 0, $last_a
if ($depth == 0 && $count == 0) {
if ($count == $total) {
html_print_image ("operation/tree/no_branch.png", false, array ("style" => 'vertical-align: middle;'));
} else {
}
else {
html_print_image ("operation/tree/first_leaf.png", false, array ("style" => 'vertical-align: middle;'));
}
} else if ($count == $total) {
}
else if ($count == $total) {
html_print_image ("operation/tree/last_leaf.png", false, array ("style" => 'vertical-align: middle;'));
} else {
}
else {
html_print_image ("operation/tree/leaf.png", false, array ("style" => 'vertical-align: middle;'));
}
}
@ -100,8 +107,6 @@ function snmp_browser_print_tree ($tree, $id = 0, $depth = 0, $last = 0, $last_a
echo "<a onfocus='javascript: this.blur();' href='javascript: snmpGet(\"" . addslashes($sub_level['__OID__']) . "\");'>";
html_print_image ("images/computer_error.png", false, array ("style" => 'vertical-align: middle;'));
echo "</a>";
} else {
}
echo '<span>' . $level . '</span>';
@ -176,7 +181,8 @@ function snmp_browser_get_tree ($target_ip, $community, $starting_oid = '.') {
$ptr = &$ptr[$sub_oid]['__LEAVES__'];
$sub_oid = '';
} else {
}
else {
if ($oid[$i] != '"') {
$sub_oid .= $oid[$i];
}
@ -252,7 +258,8 @@ function snmp_browser_get_oid ($target_ip, $community, $target_oid) {
$full_value = explode (':', trim ($full_oid[1]));
if (! isset ($full_value[1])) {
$oid_data['value'] = trim ($full_oid[1]);
} else {
}
else {
$oid_data['type'] = trim($full_value[0]);
$oid_data['value'] = trim($full_value[1]);
}
@ -323,5 +330,4 @@ function snmp_browser_print_oid ($oid = array()) {
echo '</a>';
html_print_table($table, false);
}
?>

View File

@ -436,13 +436,16 @@ function hbar_graph($flash_chart, $chart_data, $width, $height, $color = array()
function pie3d_graph($flash_chart, $chart_data, $width, $height,
$others_str = "other", $homedir="", $water_mark = "", $font = '',
$font_size = '', $ttl = 1, $legend_position = false) {
return pie_graph('3d', $flash_chart, $chart_data, $width, $height,
$others_str, $homedir, $water_mark, $font, $font_size, $ttl, $legend_position);
$others_str, $homedir, $water_mark, $font, $font_size, $ttl,
$legend_position);
}
function pie2d_graph($flash_chart, $chart_data, $width, $height,
$others_str = "other", $homedir="", $water_mark = "", $font = '',
$font_size = '', $ttl = 1, $legend_position = false) {
return pie_graph('2d', $flash_chart, $chart_data, $width, $height,
$others_str, $homedir, $water_mark, $font, $font_size, $ttl, $legend_position);
}

View File

@ -0,0 +1,756 @@
/*
Flot plugin for rendering pie charts. The plugin assumes the data is
coming is as a single data value for each series, and each of those
values is a positive value or zero (negative numbers don't make
any sense and will cause strange effects). The data values do
NOT need to be passed in as percentage values because it
internally calculates the total and percentages.
* Created by Brian Medendorp, June 2009
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
* Changes:
2009-10-22: lineJoin set to round
2009-10-23: IE full circle fix, donut
2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
2009-11-17: Added IE hover capability submitted by Anthony Aragues
2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
Available options are:
series: {
pie: {
show: true/false
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
offset: {
top: integer value to move the pie up or down
left: integer value to move the pie left or right, or 'auto'
},
stroke: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
width: integer pixel width of the stroke
},
label: {
show: true/false, or 'auto'
formatter: a user-defined function that modifies the text/style of the label text
radius: 0-1 for percentage of fullsize, or a specified pixel length
background: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
opacity: 0-1
},
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
},
combine: {
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
label: any text value of what the combined slice should be labeled
}
highlight: {
opacity: 0-1
}
}
}
More detail and specific examples can be found in the included HTML file.
*/
(function ($)
{
function init(plot) // this is the "body" of the plugin
{
var canvas = null;
var target = null;
var maxRadius = null;
var centerLeft = null;
var centerTop = null;
var total = 0;
var redraw = true;
var redrawAttempts = 10;
var shrink = 0.95;
var legendWidth = 0;
var processed = false;
var raw = false;
// interactive variables
var highlights = [];
// add hook to determine if pie plugin in enabled, and then perform necessary operations
plot.hooks.processOptions.push(checkPieEnabled);
plot.hooks.bindEvents.push(bindEvents);
// check to see if the pie plugin is enabled
function checkPieEnabled(plot, options)
{
if (options.series.pie.show)
{
//disable grid
options.grid.show = false;
// set labels.show
if (options.series.pie.label.show=='auto')
if (options.legend.show)
options.series.pie.label.show = false;
else
options.series.pie.label.show = true;
// set radius
if (options.series.pie.radius=='auto')
if (options.series.pie.label.show)
options.series.pie.radius = 3/4;
else
options.series.pie.radius = 1;
// ensure sane tilt
if (options.series.pie.tilt>1)
options.series.pie.tilt=1;
if (options.series.pie.tilt<0)
options.series.pie.tilt=0;
// add processData hook to do transformations on the data
plot.hooks.processDatapoints.push(processDatapoints);
plot.hooks.drawOverlay.push(drawOverlay);
// add draw hook
plot.hooks.draw.push(draw);
}
}
// bind hoverable events
function bindEvents(plot, eventHolder)
{
var options = plot.getOptions();
if (options.series.pie.show && options.grid.hoverable)
eventHolder.unbind('mousemove').mousemove(onMouseMove);
if (options.series.pie.show && options.grid.clickable)
eventHolder.unbind('click').click(onClick);
}
// debugging function that prints out an object
function alertObject(obj)
{
var msg = '';
function traverse(obj, depth)
{
if (!depth)
depth = 0;
for (var i = 0; i < obj.length; ++i)
{
for (var j=0; j<depth; j++)
msg += '\t';
if( typeof obj[i] == "object")
{ // its an object
msg += ''+i+':\n';
traverse(obj[i], depth+1);
}
else
{ // its a value
msg += ''+i+': '+obj[i]+'\n';
}
}
}
traverse(obj);
alert(msg);
}
function calcTotal(data)
{
for (var i = 0; i < data.length; ++i)
{
var item = parseFloat(data[i].data[0][1]);
if (item)
total += item;
}
}
function processDatapoints(plot, series, data, datapoints)
{
if (!processed)
{
processed = true;
canvas = plot.getCanvas();
target = $(canvas).parent();
options = plot.getOptions();
plot.setData(combine(plot.getData()));
}
}
function setupPie()
{
legendWidth = target.children().filter('.legend').children().width();
// calculate maximum radius and center point
maxRadius = Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
centerTop = (canvas.height/2)+options.series.pie.offset.top;
centerLeft = (canvas.width/2);
if (options.series.pie.offset.left=='auto')
if (options.legend.position.match('w'))
centerLeft += legendWidth/2;
else
centerLeft -= legendWidth/2;
else
centerLeft += options.series.pie.offset.left;
if (centerLeft<maxRadius)
centerLeft = maxRadius;
else if (centerLeft>canvas.width-maxRadius)
centerLeft = canvas.width-maxRadius;
}
function fixData(data)
{
for (var i = 0; i < data.length; ++i)
{
if (typeof(data[i].data)=='number')
data[i].data = [[1,data[i].data]];
else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
{
if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
data[i].label = data[i].data.label; // fix weirdness coming from flot
data[i].data = [[1,0]];
}
}
return data;
}
function combine(data)
{
data = fixData(data);
calcTotal(data);
var combined = 0;
var numCombined = 0;
var color = options.series.pie.combine.color;
var newdata = [];
for (var i = 0; i < data.length; ++i)
{
// make sure its a number
data[i].data[0][1] = parseFloat(data[i].data[0][1]);
if (!data[i].data[0][1])
data[i].data[0][1] = 0;
if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
{
combined += data[i].data[0][1];
numCombined++;
if (!color)
color = data[i].color;
}
else
{
newdata.push({
data: [[1,data[i].data[0][1]]],
color: data[i].color,
label: data[i].label,
angle: (data[i].data[0][1]*(Math.PI*2))/total,
percent: (data[i].data[0][1]/total*100)
});
}
}
if (numCombined>0)
newdata.push({
data: [[1,combined]],
color: color,
label: options.series.pie.combine.label,
angle: (combined*(Math.PI*2))/total,
percent: (combined/total*100)
});
return newdata;
}
function draw(plot, newCtx)
{
if (!target) return; // if no series were passed
ctx = newCtx;
setupPie();
var slices = plot.getData();
var attempts = 0;
while (redraw && attempts<redrawAttempts)
{
redraw = false;
if (attempts>0)
maxRadius *= shrink;
attempts += 1;
clear();
if (options.series.pie.tilt<=0.8)
drawShadow();
drawPie();
}
if (attempts >= redrawAttempts) {
clear();
target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
}
if ( plot.setSeries && plot.insertLegend )
{
plot.setSeries(slices);
plot.insertLegend();
}
// we're actually done at this point, just defining internal functions at this point
function clear()
{
ctx.clearRect(0,0,canvas.width,canvas.height);
target.children().filter('.pieLabel, .pieLabelBackground').remove();
}
function drawShadow()
{
var shadowLeft = 5;
var shadowTop = 15;
var edge = 10;
var alpha = 0.02;
// set radius
if (options.series.pie.radius>1)
var radius = options.series.pie.radius;
else
var radius = maxRadius * options.series.pie.radius;
if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
return; // shadow would be outside canvas, so don't draw it
ctx.save();
ctx.translate(shadowLeft,shadowTop);
ctx.globalAlpha = alpha;
ctx.fillStyle = '#000';
// center and rotate to starting position
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//radius -= edge;
for (var i=1; i<=edge; i++)
{
ctx.beginPath();
ctx.arc(0,0,radius,0,Math.PI*2,false);
ctx.fill();
radius -= i;
}
ctx.restore();
}
function drawPie()
{
startAngle = Math.PI*options.series.pie.startAngle;
// set radius
if (options.series.pie.radius>1)
var radius = options.series.pie.radius;
else
var radius = maxRadius * options.series.pie.radius;
// center and rotate to starting position
ctx.save();
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
// draw slices
ctx.save();
var currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i)
{
slices[i].startAngle = currentAngle;
drawSlice(slices[i].angle, slices[i].color, true);
}
ctx.restore();
// draw slice outlines
ctx.save();
ctx.lineWidth = options.series.pie.stroke.width;
currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i)
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
ctx.restore();
// draw donut hole
drawDonutHole(ctx);
// draw labels
if (options.series.pie.label.show)
drawLabels();
// restore to original state
ctx.restore();
function drawSlice(angle, color, fill)
{
if (angle<=0)
return;
if (fill)
ctx.fillStyle = color;
else
{
ctx.strokeStyle = color;
ctx.lineJoin = 'round';
}
ctx.beginPath();
if (Math.abs(angle - Math.PI*2) > 0.000000001)
ctx.moveTo(0,0); // Center of the pie
//--------------------------------------------------
//JQUERY 1.9 DOES NOT SUPPORT THE BROWSER
//PANDORA FMS TEAM DISABLED THIS LINES
//else if ($.browser.msie)
// angle -= 0.0001;
//--------------------------------------------------
//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
ctx.closePath();
//ctx.rotate(angle); // This doesn't work properly in Opera
currentAngle += angle;
if (fill)
ctx.fill();
else
ctx.stroke();
}
function drawLabels()
{
var currentAngle = startAngle;
// set radius
if (options.series.pie.label.radius>1)
var radius = options.series.pie.label.radius;
else
var radius = maxRadius * options.series.pie.label.radius;
for (var i = 0; i < slices.length; ++i)
{
if (slices[i].percent >= options.series.pie.label.threshold*100)
drawLabel(slices[i], currentAngle, i);
currentAngle += slices[i].angle;
}
function drawLabel(slice, startAngle, index)
{
if (slice.data[0][1]==0)
return;
// format label text
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
if (lf)
text = lf(slice.label, slice);
else
text = slice.label;
if (plf)
text = plf(text, slice);
var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
target.append(html);
var label = target.children('#pieLabel'+index);
var labelTop = (y - label.height()/2);
var labelLeft = (x - label.width()/2);
label.css('top', labelTop);
label.css('left', labelLeft);
// check to make sure that the label is not outside the canvas
if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
redraw = true;
if (options.series.pie.label.background.opacity != 0) {
// put in the transparent background separately to avoid blended labels and label boxes
var c = options.series.pie.label.background.color;
if (c == null) {
c = slice.color;
}
var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
}
} // end individual label function
} // end drawLabels function
} // end drawPie function
} // end draw function
// Placed here because it needs to be accessed from multiple locations
function drawDonutHole(layer)
{
// draw donut hole
if(options.series.pie.innerRadius > 0)
{
// subtract the center
layer.save();
innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
layer.beginPath();
layer.fillStyle = options.series.pie.stroke.color;
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
layer.fill();
layer.closePath();
layer.restore();
// add inner stroke
layer.save();
layer.beginPath();
layer.strokeStyle = options.series.pie.stroke.color;
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
layer.stroke();
layer.closePath();
layer.restore();
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
}
}
//-- Additional Interactive related functions --
function isPointInPoly(poly, pt)
{
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
function findNearbySlice(mouseX, mouseY)
{
var slices = plot.getData(),
options = plot.getOptions(),
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
for (var i = 0; i < slices.length; ++i)
{
var s = slices[i];
if(s.pie.show)
{
ctx.save();
ctx.beginPath();
ctx.moveTo(0,0); // Center of the pie
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
ctx.closePath();
x = mouseX-centerLeft;
y = mouseY-centerTop;
if(ctx.isPointInPath)
{
if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
{
//alert('found slice!');
ctx.restore();
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
}
}
else
{
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
p1X = (radius * Math.cos(s.startAngle));
p1Y = (radius * Math.sin(s.startAngle));
p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
p5X = (radius * Math.cos(s.startAngle+s.angle));
p5Y = (radius * Math.sin(s.startAngle+s.angle));
arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
arrPoint = [x,y];
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
if(isPointInPoly(arrPoly, arrPoint))
{
ctx.restore();
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
}
}
ctx.restore();
}
}
return null;
}
function onMouseMove(e)
{
triggerClickHoverEvent('plothover', e);
}
function onClick(e)
{
triggerClickHoverEvent('plotclick', e);
}
// trigger click or hover event (they send the same parameters so we share their code)
function triggerClickHoverEvent(eventname, e)
{
var offset = plot.offset(),
canvasX = parseInt(e.pageX - offset.left),
canvasY = parseInt(e.pageY - offset.top),
item = findNearbySlice(canvasX, canvasY);
if (options.grid.autoHighlight)
{
// clear auto-highlights
for (var i = 0; i < highlights.length; ++i)
{
var h = highlights[i];
if (h.auto == eventname && !(item && h.series == item.series))
unhighlight(h.series);
}
}
// highlight the slice
if (item)
highlight(item.series, eventname);
// trigger any hover bind events
var pos = { pageX: e.pageX, pageY: e.pageY };
target.trigger(eventname, [ pos, item ]);
}
function highlight(s, auto)
{
if (typeof s == "number")
s = series[s];
var i = indexOfHighlight(s);
if (i == -1)
{
highlights.push({ series: s, auto: auto });
plot.triggerRedrawOverlay();
}
else if (!auto)
highlights[i].auto = false;
}
function unhighlight(s)
{
if (s == null)
{
highlights = [];
plot.triggerRedrawOverlay();
}
if (typeof s == "number")
s = series[s];
var i = indexOfHighlight(s);
if (i != -1)
{
highlights.splice(i, 1);
plot.triggerRedrawOverlay();
}
}
function indexOfHighlight(s)
{
for (var i = 0; i < highlights.length; ++i)
{
var h = highlights[i];
if (h.series == s)
return i;
}
return -1;
}
function drawOverlay(plot, octx)
{
//alert(options.series.pie.radius);
var options = plot.getOptions();
//alert(options.series.pie.radius);
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
octx.save();
octx.translate(centerLeft, centerTop);
octx.scale(1, options.series.pie.tilt);
for (i = 0; i < highlights.length; ++i)
drawHighlight(highlights[i].series);
drawDonutHole(octx);
octx.restore();
function drawHighlight(series)
{
if (series.angle < 0) return;
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
octx.beginPath();
if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
octx.moveTo(0,0); // Center of the pie
octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
octx.closePath();
octx.fill();
}
}
} // end init (plugin body)
// define pie specific options and their default values
var options = {
series: {
pie: {
show: false,
radius: 'auto', // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
innerRadius:0, /* for donut */
startAngle: 3/2,
tilt: 1,
offset: {
top: 0,
left: 'auto'
},
stroke: {
color: '#FFF',
width: 1
},
label: {
show: 'auto',
formatter: function(label, slice){
return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
}, // formatter function
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
background: {
color: null,
opacity: 0
},
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
},
combine: {
threshold: -1, // percentage at which to combine little slices into one larger slice
color: null, // color to give the new slice (auto-generated if null)
label: 'Other' // label to give the new slice
},
highlight: {
//color: '#FFF', // will add this functionality once parseColor is available
opacity: 0.5
}
}
}
};
$.plot.plugins.push({
init: init,
options: options,
name: "pie",
version: "1.0"
});
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -7,8 +7,7 @@ function pandoraFlotPie(graph_id, values, labels, nseries, width, font_size, wat
var labels = labels.split(separator);
var data = values.split(separator);
for( var i = 0; i<nseries; i++)
{
for (var i = 0; i < nseries; i++) {
data[i] = { label: labels[i], data: parseInt(data[i]) }
}
@ -24,7 +23,9 @@ function pandoraFlotPie(graph_id, values, labels, nseries, width, font_size, wat
show: true,
radius: 3/4,
formatter: function(label, series) {
return '<div style="font-size:'+font_size+'pt;text-align:center;padding:2px;color:white;">'+label+'<br/>'+Math.round(series.percent)+'%</div>';
return '<div style="font-size:' + font_size + 'pt;' +
'text-align:center;padding:2px;color:white;">' +
label + '<br/>' + Math.round(series.percent) + '%</div>';
},
background: {
opacity: 0.5,
@ -102,7 +103,8 @@ function pandoraFlotPie(graph_id, values, labels, nseries, width, font_size, wat
}
if (water_mark) {
set_watermark(graph_id, plot, $('#watermark_image_'+graph_id).attr('src'));
set_watermark(graph_id, plot,
$('#watermark_image_' + graph_id).attr('src'));
}
}
@ -996,7 +998,8 @@ function adjust_menu(graph_id, plot, parent_height) {
overview_height = parseInt($('#overview_'+graph_id).css('height').split('px')[0]) + parseInt($('#overview_'+graph_id).css('margin-top').split('px')[0]);
}
$('#menu_'+graph_id).css('top',(-parent_height+legend_height-overview_height-7)+'px');
$('#menu_'+graph_id).css('top',
(-parent_height+legend_height-overview_height-7)+'px');
$('#menu_'+graph_id).css('left',plot.width()-(left_ticks_width/2));
$('#menu_'+graph_id).show();
}

View File

@ -36,7 +36,7 @@ function include_javascript_dependencies_flot_graph($return = false) {
<script language="javascript" type="text/javascript" src="'.
ui_get_full_url($metaconsole_hack . '/include/graphs/flot/jquery.flot.min.js') .'"></script>
<script language="javascript" type="text/javascript" src="'.
ui_get_full_url($metaconsole_hack . '/include/graphs/flot/jquery.flot.pie.min.js') .'"></script>
ui_get_full_url($metaconsole_hack . '/include/graphs/flot/jquery.flot.pie.js') .'"></script>
<script language="javascript" type="text/javascript" src="'.
ui_get_full_url($metaconsole_hack . '/include/graphs/flot/jquery.flot.crosshair.min.js') .'"></script>
<script language="javascript" type="text/javascript" src="'.

View File

@ -108,7 +108,8 @@ else if ($modulegroup > -1) {
// Module name selector
if ($ag_modulename != "") {
$sql_conditions .= sprintf (" AND tagente_modulo.nombre = '%s'", $ag_modulename);
$sql_conditions .= sprintf (" AND tagente_modulo.nombre = '%s'",
$ag_modulename);
}
// Freestring selector