#
#
# build_html_graphs_util.cfv
# Graph utilities used in build_html_standard()
# The utilities build the html part of a graph
#
#
#
# get_y_label_table_width()
#
# get_x_label_table_with_labels_on_ticks()
# get_x_label_table_with_single_label_on_tick()
# get_x_label_table_with_labels_between_ticks()
# get_x_label_table()
#
# get_y_label_spacer_image_fileref()
# get_left_and_right_y_label_tables()
#
# build_graph_legend_table()
#
#
#
include "templates.util.encoding";
include "templates.util.colors";
#
#
#
# get_y_label_table_width()
#
# Gets the width for the y_label table among all displayed graphs.
#
subroutine(get_y_label_table_width(
node query_fields,
string profile_name,
node raw_report_element_graphs), (
debug_message("\n\n#### get_y_label_table_width \n\n");
node raw_report_element_graph_item;
string graph_id;
node raw_graph;
string report_field_name;
string display_format_type;
node y_ticks;
node tick;
string tick_label;
int tick_label_length;
int max_character_in_y_label_among_all_graphs = 0;
foreach raw_report_element_graph_item raw_report_element_graphs (
graph_id = @raw_report_element_graph_item;
raw_graph = "profiles_cache." . profile_name . ".raw_graphs." . graph_id;
report_field_name = @raw_graph{"report_field_name"};
display_format_type = @query_fields{report_field_name}{"display_format_type"};
y_ticks = raw_graph . ".y_data.ticks";
foreach tick y_ticks (
tick_label = format(@tick{"label"}, display_format_type);
debug_message("#### get_y_label_table_width() - tick_label: " . tick_label . "\n");
tick_label_length = length(tick_label);
if (tick_label_length > max_character_in_y_label_among_all_graphs) then (
max_character_in_y_label_among_all_graphs = tick_label_length;
);
);
);
int y_label_table_width = (6 * max_character_in_y_label_among_all_graphs) + 18; # 6px for char width and 18px left margin
y_label_table_width;
));
#
#
#
# get_x_label_table_with_labels_on_ticks()
#
#
#
subroutine(get_x_label_table_with_labels_on_ticks(
int y_label_table_width,
node x_ticks_with_labels,
int number_of_x_ticks_with_labels), (
debug_message("\n\n#### get_x_label_table_with_labels_on_ticks() \n");
# Note, the distance between the x-ticks may vary depending on the chronological
# granularity. So the table cell width may vary from x-tick to x-tick
node current_tick;
node next_tick;
string the_label;
int current_tick_position;
int next_tick_position;
int distance_between_two_ticks;
int a = 0; # The left side of a tick we use for the table cell
int b = 0; # The right side of a tick we use for the table cell
int cell_width; # a + b
int table_width;
int spacer_cell_width;
'
';
for (int count = 0; count < number_of_x_ticks_with_labels; count++) (
current_tick = subnode_by_number(x_ticks_with_labels, count);
current_tick_position = y_label_table_width + @current_tick{"position"};
the_label = get_expanded_label(@current_tick{"label"});
if ((count + 1) < number_of_x_ticks_with_labels) then (
next_tick = subnode_by_number(x_ticks_with_labels, count + 1);
next_tick_position = y_label_table_width + @next_tick{"position"};
distance_between_two_ticks = next_tick_position - current_tick_position;
b = distance_between_two_ticks / 2;
if (count != 0) then (
a = current_tick_position - table_width;
cell_width = a + b;
table_width = table_width + cell_width;
)
else (
# This is the first tick, add the first spacer cell and set the initial table width
a = b;
cell_width = a + b;
table_width = current_tick_position + b;
spacer_cell_width = table_width - cell_width;
# Add the spacer cell
' | ';
);
)
else (
# This is the last x-tick, so there is no next_tick
a = current_tick_position - table_width;
cell_width = 2 * a;
);
# debug_message("#### cell_width: " . cell_width . "\n");
'';
'' . the_label . '';
' | ';
);
'
';
));
#
#
#
# get_x_label_table_with_single_label_on_tick()
#
#
#
subroutine(get_x_label_table_with_single_label_on_tick(
int y_label_table_width,
node x_ticks_with_labels), (
node first_tick = subnode_by_number(x_ticks_with_labels, 0);
int first_tick_position = @first_tick{"position"};
int width_up_to_first_tick = y_label_table_width + first_tick_position;
# there is only one label
int cell_width = width_up_to_first_tick * 2;
string the_label = get_expanded_label(@first_tick{"label"});
'';
'' . the_label . ' | ';
'
';
));
#
#
#
# get_x_label_table_with_labels_between_ticks()
#
#
#
subroutine(get_x_label_table_with_labels_between_ticks(
int y_label_table_width,
node x_ticks_with_labels,
int number_of_x_ticks_with_labels), (
# node tick_1_node = subnode_by_number(x_ticks_with_labels, 0);
# int tick_1 = node_value(subnode_by_name(tick_1_node, "position"));
# int width_up_to_first_tick = y_label_table_width + tick_1;
node first_tick = subnode_by_number(x_ticks_with_labels, 0);
int first_tick_position = @first_tick{"position"};
int width_up_to_first_tick = y_label_table_width + first_tick_position;
#
#
# x labels are on tick center, labels are positioned between ticks
#
#
'';
# spacer cell
' | ';
node left_tick_position_node;
node right_tick_position_node;
int left_tick_position;
int right_tick_position;
int cell_width;
string the_label;
for (int count = 0; count < (number_of_x_ticks_with_labels - 1); count++) (
left_tick_position_node = subnode_by_number(x_ticks_with_labels, count);
right_tick_position_node = subnode_by_number(x_ticks_with_labels, count + 1);
left_tick_position = node_value(subnode_by_name(left_tick_position_node, "position"));
right_tick_position = node_value(subnode_by_name(right_tick_position_node, "position"));
cell_width = right_tick_position - left_tick_position;
the_label = get_expanded_label(@left_tick_position_node{"label"});
'' . the_label . ' | ';
);
'
';
'
';
));
#
#
#
# get_x_label_table()
#
#
#
subroutine(get_x_label_table(
string profile_name,
node raw_report_element_graphs,
int y_label_table_width), (
debug_message("\n\n#### get_x_label_table START \n");
debug_message("#### y_label_table_width: " . y_label_table_width . "\n");
#
#
# Get the first raw_graph
#
#
string graph_id = node_value(subnode_by_number(raw_report_element_graphs, 0));
node raw_graph = "profiles_cache." . profile_name . ".raw_graphs." . graph_id;
# int image_width = @raw_graph{"image_width"};
bool x_label_on_tick_center = @(raw_graph . ".x_data.is_label_on_tick_center");
# Clone x_ticks to a temporary node
delete_node("v.x_ticks_with_labels");
v.x_ticks_with_labels = "";
node x_ticks_with_labels = "v.x_ticks_with_labels";
clone_node(raw_graph . ".x_data.ticks", x_ticks_with_labels);
# debug_message("#### x_ticks_with_labels before clean up:\n" . node_as_string(x_ticks_with_labels) . "\n");
#
#
# clean up x_ticks node
#
#
# delete any varaible node in x_ticks where no x_label is shown
node variable;
foreach variable x_ticks_with_labels (
if (!node_value(subnode_by_name(variable, "show_label"))) then (
delete_node(variable);
);
);
debug_message("#### x_ticks_with_labels after clean up:\n" . node_as_string(x_ticks_with_labels) . "\n");
#
#
# start creating the x-labels-table
#
#
int number_of_x_ticks_with_labels = num_subnodes(x_ticks_with_labels);
# KHP 21/Sep/2010, make sure there are x-ticks before creating the table with labels
if (number_of_x_ticks_with_labels > 0) then (
if (x_label_on_tick_center) then (
if (number_of_x_ticks_with_labels > 1) then (
get_x_label_table_with_labels_on_ticks(y_label_table_width, x_ticks_with_labels, number_of_x_ticks_with_labels);
)
else (
get_x_label_table_with_single_label_on_tick(y_label_table_width, x_ticks_with_labels);
);
)
else (
get_x_label_table_with_labels_between_ticks(y_label_table_width, x_ticks_with_labels, number_of_x_ticks_with_labels);
);
)
else (
# KHP 21/Sep/2010, there are no x-tick labels, return empty table.
'';
);
debug_message("\n\n#### get_x_label_table END \n");
));
#
#
#
# get_y_label_spacer_image_fileref()
#
#
#
subroutine(get_y_label_spacer_image_fileref(
string profile_name,
string graphs_profile_directory_path,
int y_label_table_width), (
int image_width = y_label_table_width;
int image_height = 1;
string image_filename = "y_space_" . image_width . ".gif";
string image_path = graphs_profile_directory_path . image_filename;
if (!file_exists(image_path)) then (
# Create spacer image
string img = create_image(image_width, image_height);
string img_color = allocate_image_color(img, 255, 255, 255);
add_rectangle_to_image(img, img_color, 0, 0, image_width - 1, image_height - 1, true);
write_image_to_disk(img, image_path, "GIF");
);
string image_filref = fileref("graphs/" . profile_name . "/" . image_filename);
image_filref;
));
#
#
#
# get_left_and_right_y_label_tables()
#
#
#
subroutine(get_left_and_right_y_label_tables(
node query_fields,
node raw_graph,
node html_formatting), (
# string number_decimal_divider = @html_formatting{"number_decimal_divider"};
node y_data = raw_graph{"y_data"};
string report_field_name = @raw_graph{"report_field_name"};
string display_format_type = @(query_fields . "." . report_field_name . ".display_format_type");
string y_label_table_left = '';
string y_label_table_right = '';
node y_ticks = y_data{"ticks"};
int number_of_y_ticks = num_subnodes(y_ticks);
int y_cell_height = @y_data{"tick_interval"};
node y_tick_item;
string y_tick_label;
string y_tick_percentage;
for (int i = (number_of_y_ticks - 1); i > -1; i--) (
y_tick_item = y_ticks{i};
y_tick_label = format(@y_tick_item{"label"}, display_format_type);
y_tick_percentage = format(@y_tick_item{"percentage"}, "%.1f");
y_label_table_left .= '' . y_tick_label . ' |
';
y_label_table_right .= '' . y_tick_percentage . ' % |
';
);
# add the 0 label
y_label_table_left .= '0 |
';
y_label_table_right .= '0 % |
';
y_label_table_left .= '
';
y_label_table_right .= '
';
#
# Return the 2 tables in a node
#
v.temp_y_label_tables = "";
v.temp_y_label_tables.y_label_table_left = y_label_table_left;
v.temp_y_label_tables.y_label_table_right = y_label_table_right;
"v.temp_y_label_tables";
));
subroutine(build_graph_legend_table(
node query_fields,
string profile_name,
node raw_graph,
string color_scheme,
node mixed_colors_node,
node remainder_color_node), (
# debug_message("\n\n#### build_graph_legend_table() START \n\n");
# KHP-RC, revise color support (colors should be in raw_graph!)
string graph_type = @raw_graph{"graph_type"};
int show_color_icon = if (color_scheme eq "mixed") then (true) else (false);
bool last_variable_is_remainder = @raw_graph{"last_variable_is_remainder"};
node legend_header = raw_graph . ".legend.header";
node legend_rows = raw_graph . ".legend.rows";
bool is_multiple_legend_columns = if (num_subnodes(legend_header) > 1) then (true) else (false);
node row;
int row_count = 1;
int color_count = 0;
int number_of_colors = if (show_color_icon) then (num_subnodes(mixed_colors_node)) else (0);
int r;
int g;
int b;
node column;
int column_count;
int last_column_number = if (is_multiple_legend_columns) then (num_subnodes(legend_header) - 1) else (0);
string report_field_name;
string display_format_type;
string legend_label;
string table_class_name = if (graph_type ne "pie") then ("graph-legend") else ("pie-chart-legend");
'\n';
foreach row legend_rows (
'\n';
'' . row_count . ' | \n';
if (show_color_icon) then (
r = node_value(mixed_colors_node . "." . color_count . ".red");
g = node_value(mixed_colors_node . "." . color_count . ".green");
b = node_value(mixed_colors_node . "." . color_count . ".blue");
'';
'';
' | \n';
);
column_count = 0;
legend_label = "";
foreach column legend_header (
report_field_name = @column{"report_field_name"};
display_format_type = @(query_fields . "." . report_field_name . ".display_format_type");
# debug_message("#### build_graph_legend_table() - report_field_name: " . report_field_name . "\n");
# debug_message("#### build_graph_legend_table() - display_format_type: " . display_format_type . "\n");
legend_label .= format(node_value(subnode_by_number(row, column_count)), display_format_type);
if (is_multiple_legend_columns and (column_count != last_column_number)) then (
legend_label .= ", ";
);
column_count++;
);
'' . string_to_html(legend_label) . ' | ';
row_count++;
if (show_color_icon) then (
color_count++;
if (color_count == number_of_colors) then (
# start repeating the colors
color_count = 0;
);
);
'
\n';
);
if (last_variable_is_remainder) then (
int number_of_remainder_items = @raw_graph{"number_of_remainder_items"};
node variables = raw_graph{"variables"};
int number_of_variables = num_subnodes(variables);
volatile.param1 = number_of_remainder_items;
'\n';
'' . number_of_variables . ' | \n';
if (show_color_icon) then (
r = @remainder_color_node{"red"};
g = @remainder_color_node{"green"};
b = @remainder_color_node{"blue"};
'';
'';
' | \n';
);
'' . expand(lang_stats.graph.remaining_items) . ' | \n';
'
\n';
);
'
\n';
));