# # # 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_label_table_right .= ''; ); # add the 0 label y_label_table_left .= ''; y_label_table_right .= ''; y_label_table_left .= '
' . y_tick_label . '
' . y_tick_percentage . ' %
0
0 %
'; 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'; '\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++; ); ''; 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'; '\n'; if (show_color_icon) then ( r = @remainder_color_node{"red"}; g = @remainder_color_node{"green"}; b = @remainder_color_node{"blue"}; '\n'; ); '\n'; '\n'; ); '
' . row_count . ''; '
'; '
' . string_to_html(legend_label) . '
' . number_of_variables . ''; '
'; '
' . expand(lang_stats.graph.remaining_items) . '
\n'; ));