/branches/3.2/src/manhat-lib/shared_survey_bar_graph.c
# · C · 815 lines · 626 code · 187 blank · 2 comment · 123 complexity · a7b75e32d96984313f14653be3366039 MD5 · raw file
- #include <stdio.h>
- #include "../global.h"
- #include "shared_survey_bar_graph.h"
- #include "shared_survey_string.h"
- #include "shared_survey_util.h"
- #include "shared_survey_xml_parser.h"
- #include "shared_record_parser.h"
- double likert_total =0;
- double likert_count=0;
- static int
- contains_empty_response(RESULT *one_result)
- {
-
- VALUE_COUNT *ptr;
- for(ptr = one_result->value_head; ptr; ptr = ptr->next)
- if(atoi(ptr->value) == -1)
- return 1;
- return 0;
- }
-
-
- static void
- nl_to_space(char *string)
- {
- char *ptr;
-
- for(ptr=string; *ptr; ptr++)
- if( (*ptr==10) || (*ptr == 13) || *ptr == '\'' || *ptr == '\"')
- *ptr = ' ';
- }
-
- void replace_quotes(char *str)
- {
- int i, len;
- len = strlen(str);
- for(i = 0; i<len; i++)
- {
- if(str[i] == '\"' || str[i] == '\'')
- str[i] = ' ';
- }
- }
- static
- void set_likert_choice_common_values(SURVEY_DATA *data, int question_number, int steps, char *question_type, int bar_graph_count)
- {
- #define MAX_TMP_NAME 50
- char name[MAX_TMP_NAME];
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.type", bar_graph_count);
- cs_set_value(name, question_type);
- nl_to_space(data->caption);
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.title", bar_graph_count);
- cs_set_value(name, data->caption);
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.question_number", bar_graph_count);
- cs_set_int_value(name, question_number);
- #undef MAX_TMP_NAME
- }
-
- static void
- set_likert_values(SURVEY_DATA *likert, RESULT *one_result, int question_number, int bar_graph_count)
- {
- #define MAX_TMP_NAME 50
- int i;
- int steps;
- char name[MAX_TMP_NAME];
- char tmp_value[MAX_TMP_NAME];
- int has_empty_responses = contains_empty_response(one_result);
- double average = 0;
- double total =0;
- int count = 0;
- steps = atoi(likert->steps_bgcolor);
- set_likert_choice_common_values(likert, question_number, steps, "likert", bar_graph_count);
- one_result->value_current = one_result->value_head;
- if(has_empty_responses)
- one_result->value_current = one_result->value_current->next;
- for(i =1; i<=steps; i++)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.percent.%d", bar_graph_count, i-1);
- if(one_result->value_current && atoi(one_result->value_current->value)==i)
- {
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", (float)one_result->value_current->count/(float)one_result->count*100.0);
- cs_set_value(name, tmp_value);
- one_result->value_current = one_result->value_current->next;
- }
- else
- {
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", 0.0);
- cs_set_value(name, tmp_value);
- }
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.percent.%d", bar_graph_count, i-1);
- one_result->value_current = one_result->value_head;
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", (float)one_result->value_current->count/(float)one_result->count*100.0);
- cs_set_value(name, tmp_value);
- }
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.number_choices", bar_graph_count);
- cs_set_int_value(name, has_empty_responses ? i: i-1);
- for(i =1; i<=steps; i++)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.XScale.%d", bar_graph_count, i-1);
- cs_set_int_value(name, i);
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.XScale.%d", bar_graph_count, i-1);
- cs_set_int_value(name, -1);
- }
-
- for(i = 0; i<steps; i++)
- {
- char temp[MAX_PATH +1];
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.legend.%d", bar_graph_count, i);
- if(i == steps -1)
- {
- nl_to_space(likert->right_rows);
- snprintf(temp, MAX_PATH +1, "%s %d", likert->right_rows, i+1);
- cs_set_value(name, temp);
- }
- else if(i == 0)
- {
- nl_to_space(likert->left_cols);
- snprintf(temp, MAX_PATH +1, "%s %d", likert->left_cols, i+1);
- cs_set_value(name, temp);
- }
- else
- {
- snprintf(temp, MAX_PATH +1, "%d", i+1);
- cs_set_value(name, temp);
- }
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.noanswer", bar_graph_count);
- cs_set_int_value(name, 1);
- }
- one_result->value_current = one_result->value_head;
- if(has_empty_responses)
- one_result->value_current = one_result->value_current->next;
- for(i =1; i<=steps; i++)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.count.%d", bar_graph_count, i-1);
- if(one_result->value_current && atoi(one_result->value_current->value)==i)
- {
- cs_set_int_value(name, one_result->value_current->count);
- total += i * one_result->value_current->count;
- count += one_result->value_current->count;
- one_result->value_current = one_result->value_current->next;
-
- }
- else
- cs_set_int_value(name, 0);
- }
- if(count > 0)
- average = total / count;
- likert_total += average;
- likert_count++;
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.count.%d", bar_graph_count, i-1);
- one_result->value_current = one_result->value_head;
- cs_set_int_value(name, one_result->value_current->count);
- }
- #undef MAX_TMP_NAME
- }
- static int
- get_choice_count(SURVEY_DATA *choice)
- {
- int i = 0;
- choice->current = choice->head;
- while(choice->current)
- {
- i++;
- choice->current = choice->current->next;
- }
- return i;
- }
- static void
- set_choice_values(SURVEY_DATA *choice, RESULT *one_result, int question_number, int bar_graph_count )
- {
- #define MAX_TMP_NAME 100
- int i =1;
- int has_empty_responses = contains_empty_response(one_result);
- int flag = get_choice_count(choice);
- char name[MAX_TMP_NAME];
- char tmp_value[MAX_TMP_NAME];
-
- if(strcmp(choice->steps_bgcolor, "yes") ==0)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.multi", bar_graph_count);
- cs_set_int_value(name, 1);
- }
-
- set_likert_choice_common_values(choice, question_number, flag, "multi_choice", bar_graph_count);
-
- one_result->value_current = one_result->value_head;
- if(has_empty_responses)
- one_result->value_current = one_result->value_current->next;
- choice->current = choice->head;
- while(choice->current )
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.percent.%d", bar_graph_count, i-1);
-
- if(one_result->value_current && (atoi(one_result->value_current->value) == i))
- {
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", ((float)one_result->value_current->count/(float)one_result->count) * 100.0);
- cs_set_value(name, tmp_value);
- one_result->value_current = one_result->value_current->next;
- }
- else
- {
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", 0.0);
- cs_set_value(name, tmp_value);
- }
- i++;
- choice->current = choice->current->next;
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.percent.%d", bar_graph_count, i-1);
- one_result->value_current = one_result->value_head;
- snprintf(tmp_value, MAX_TMP_NAME, "%3.1f", ((float)one_result->value_current->count/(float)one_result->count) * 100.0);
- cs_set_value(name, tmp_value);
- }
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.number_choices", bar_graph_count);
- cs_set_int_value(name, has_empty_responses ? i: i-1);
-
- for(i =1; i<=flag; i++)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.XScale.%d", bar_graph_count, i-1);
- cs_set_int_value(name, i);
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.XScale.%d", bar_graph_count, i-1);
- cs_set_int_value(name, -1);
- }
-
-
- i = 1;
- choice->current = choice->head;
- while(choice->current )
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.legend.%d", bar_graph_count, i-1);
- nl_to_space(choice->current->choice);
- cs_set_value(name, choice->current->choice);
- i++;
- choice->current = choice->current->next;
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.noanswer", bar_graph_count);
- cs_set_int_value(name, 1);
- }
-
- one_result->value_current = one_result->value_head;
- if(has_empty_responses)
- one_result->value_current = one_result->value_current->next;
- choice->current = choice->head;
- i =1;
- while(choice->current )
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.count.%d", bar_graph_count, i-1);
- if(one_result->value_current && atoi(one_result->value_current->value) == i)
- {
- cs_set_int_value(name, one_result->value_current->count);
- one_result->value_current = one_result->value_current->next;
- }
- else
- cs_set_int_value(name, 0);
- i++;
- choice->current = choice->current->next;
- }
- if(has_empty_responses)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.count.%d", bar_graph_count, i-1);
- one_result->value_current = one_result->value_head;
- cs_set_int_value(name, one_result->value_current->count);
- }
- #undef MAX_TMP_NAME
- }
- static void
- set_memo_values(SURVEY_DATA *memo, RESULT *one_result, int question_number, char *question_type, int element_number)
- {
- #define MAX_TMP_NAME 50
- char name[MAX_TMP_NAME];
- int i =0;
-
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.type", element_number);
- cs_set_value(name, question_type );
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.title", element_number);
- cs_set_value(name, memo->caption);
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.question_number", element_number);
- cs_set_int_value(name, question_number);
- one_result->value_current = one_result->value_head;
- while(one_result->value_current)
- {
- if(strcmp(one_result->value_current->value, "-1") == 0)
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.no_count", element_number);
- cs_set_int_value(name, one_result->value_current->count);
- }
- else
- {
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.answer.%d", element_number, i);
- cs_set_value(name, one_result->value_current->value);
- snprintf(name, MAX_TMP_NAME, "survey.question.%d.count.%d", element_number, i);
- cs_set_int_value(name, one_result->value_current->count);
- i++;
- }
- one_result->value_current = one_result->value_current->next;
- }
- #undef MAX_TMP_NAME
- }
- static RESULT *
- get_one_result(RECORD *list, int id)
- {
- RESULT *ptr;
- ptr = list->head;
- while(ptr)
- {
- if(ptr->id == id )
- return ptr;
- ptr = ptr->next;
- }
- return 0;
- }
- static int value_cmp(const char *a, const char *b)
- {
- int value_a, value_b;
- if(!strcmp(a,b))
- return 0;
- if(!strcmp(a, "-1"))
- return -1;
- if(!strcmp(b,"-1"))
- return 1;
- value_a = atoi(a);
- value_b = atoi(b);
- if(value_a >value_b)
- return 1;
- return -1;
- }
- static RESULT *
- sort_one_result(RESULT *one)
- {
- VALUE_COUNT *q, *tail, *p, *r;
- if (one->value_head != NULL)
- {
- tail = one->value_head;
- while (tail->next)
- {
- q = tail->next;
- if (value_cmp (q->value, one->value_head->value) < 0)
- {
- tail->next = q->next;
- q->next = one->value_head;
- one->value_head = q;
-
- }
- else
- {
- r = one->value_head;
- p = r->next;
- while (value_cmp (q->value, p->value) > 0)
- {
- r = p;
- p = r->next;
- }
- if (q == p)
- tail = q;
- else
- {
- tail->next = q->next;
- q->next = p;
- r->next = q;
- }
- }
- }
- }
- return one;
- }
- static RECORD *
- sort_value_list(RECORD * list)
- {
- list->current = list->head;
- while(list->current)
- {
- list->current = sort_one_result(list->current);
- list->current = list->current->next;
- }
- return list;
- }
-
-
-
- static void
- set_response_rate_title(SURVEY_DATA *data, RECORD *list, int number_takers)
- {
- float response_rate;
- char tmp_value[MAX_PATH +1];
- char server_string[MAX_PATH +1];
- list->current = list->head;
- get_server_string(server_string, MAX_PATH);
- cs_set_value("survey.server_string", server_string);
- cs_set_int_value("survey.num_response", list->current->count);
-
- /* print number of people who could have taken the survey */
- if(number_takers == -1)
- {
- cs_set_int_value("survey.num_expect_takers", list->expect_takers);
- response_rate = (float) list->current->count/list->expect_takers;
- }
- else if(number_takers > 0)
- {
- cs_set_int_value("survey.num_expect_takers", number_takers);
- response_rate = (float)list->current->count/number_takers;
- }
-
- snprintf(tmp_value, MAX_PATH +1, "%.1f%%", response_rate * 100.0);
- cs_set_value("survey.rate", tmp_value);
- cs_set_value("survey.title", data->caption);
- }
- static
- void set_title_element(SURVEY_LIST *list, RECORD *record_list, int number_takers)
- {
- int found = 0;
-
- for(list->current = list->head; list->current && !found; list->current=list->current->next)
- {
- found = !strcmp(list->current->tag_name, "title");
- if(found)
- set_response_rate_title(list->current, record_list, number_takers);
- }
- }
- static
- void set_bar_graphs(SURVEY_LIST *list, RECORD *record_list, int *bar_graph_count)
- {
- int question_number = 0;
- RESULT *ptr;
- double average;
- char temp[MAX_PATH +1];
-
- *bar_graph_count = 0;
- for(list->current = list->head; list->current; list->current=list->current->next)
- {
- if(strcmp(list->current->tag_name, "title") !=0 && strcmp(list->current->tag_name, "custom") != 0)
- question_number++;
- /** is_likert_tag() is in shared_survey_util.c ***/
- if(is_likert_tag(list->current->tag_name) ||
- !strcmp(list->current->tag_name, "choice") )
- {
- ptr = get_one_result(record_list, list->current->id);
- if(ptr)
- {
- if(is_likert_tag(list->current->tag_name))
- set_likert_values(list->current, ptr, question_number, *bar_graph_count);
- else
- set_choice_values(list->current, ptr, question_number, *bar_graph_count);
- (*bar_graph_count)++;
- }
- }
- }
- if(likert_count >0)
- {
- average = likert_total / likert_count;
- snprintf(temp, MAX_PATH +1, "%.4f", average);
- cs_set_value("survey.likert_avg_response", temp);
- }
- }
- static void
- set_text_responses(SURVEY_LIST *list, RECORD *record_list, int bar_graph_count)
- {
- int question_number = 0;
- RESULT *ptr;
- int element_number;
-
- element_number = bar_graph_count;
-
- for(list->current = list->head; list->current; list->current=list->current->next)
- {
- if(strcmp(list->current->tag_name, "title") != 0 && strcmp(list->current->tag_name, "custom") != 0)
- question_number++;
- if(!strcmp(list->current->tag_name, "memo") ||
- !strcmp(list->current->tag_name, "text") )
- {
- ptr = get_one_result(record_list, list->current->id);
- if(ptr)
- {
- set_memo_values(list->current, ptr, question_number,
- !strcmp(list->current->tag_name, "memo")?"memo":"short-answer",
- element_number);
- element_number++;
- }
- }
- }
- }
- static int find_value_in_list(VALUE_COUNT *v_head, char *temp, int count)
- {
- VALUE_COUNT *ptr;
- for(ptr = v_head; ptr; ptr = ptr->next)
- {
- if(strcmp(ptr->value, temp) ==0)
- {
- ptr->count = ptr->count +count;
- return 1;
- }
- }
- return 0;
- }
- static VALUE_COUNT *add_node(char *new_value, VALUE_COUNT *head, int count)
- {
- VALUE_COUNT *ptr, *current;
- ptr = (VALUE_COUNT *)malloc(sizeof(VALUE_COUNT));
- if(!ptr)
- cs_critical_error(ERR_MALLOC_FAILED, "shared_survey_bar_graph");
- ptr->value = malloc_str(new_value);
- ptr->count = count;
- ptr->next =0;
- if(!head)
- head = ptr;
- else
- {
- current = head;
- while(current->next)
- {
- current = current->next;
- }
- current->next = ptr;
- }
- return head;
- }
- static void parse_value(char *temp, char *new_value)
- {
- char *ptr;
- ptr = strchr(temp, '|');
- if(!ptr)
- cs_critical_error(ERR_SURVEY_PARSE_DATA_FAILED, "Shared_survey_bar_graph");
- *ptr = '\0';
- strncpy(new_value, temp, MAX_PATH +1);
- ptr++;
- strncpy(temp, ptr, MAX_PATH +1);
-
- }
- static int get_number_data_fields(char *temp)
- {
- int count =0, len =0, i;
- len = strlen(temp);
- for(i =0; i<len; i++)
- {
- if(temp[i] == '|')
- count++;
- }
- return count;
- }
- static void free_value_count(VALUE_COUNT *head)
- {
- VALUE_COUNT *ptr;
- while(head)
- {
- ptr = head->next;
- if(head->value)
- free(head->value);
- free(head);
- head = ptr;
- }
- }
- static VALUE_COUNT *get_new_value_list(VALUE_COUNT *old)
- {
- VALUE_COUNT *v_head =0, *v_ptr;
- char temp[MAX_PATH +1];
- char new_value[MAX_PATH +1];
- int count =0, found =0, i;
- for(v_ptr = old; v_ptr; v_ptr = v_ptr->next)
- {
- strncpy(temp, v_ptr->value, MAX_PATH +1);
- count = get_number_data_fields(temp);
- if(count > 1)
- {
- for(i = 0; i<count-1; i++)
- {
- found =0;
- parse_value(temp, new_value);
- if(v_head)
- found = find_value_in_list(v_head, new_value, v_ptr->count);
-
- if(!found)
- v_head = add_node(new_value, v_head, v_ptr->count);
- }
- found =0;
- temp[strlen(temp) -1] = '\0';
- if(v_head)
- found = find_value_in_list(v_head, temp, v_ptr->count);
- if(!found)
- v_head = add_node(temp, v_head, v_ptr->count);
- }
- else
- {
- found = 0;
- temp[strlen(temp)-1] = '\0';
- if(v_head)
- found = find_value_in_list(v_head, temp, v_ptr->count);
- if(!found)
- v_head = add_node(temp, v_head, v_ptr->count);
- }
- }
- return v_head;
- }
- RECORD * parse_multi_select_data(RECORD *re_list, int id)
- {
- RESULT *ptr;
- VALUE_COUNT *v_head =0;
- for(ptr = re_list->head; ptr; ptr = ptr->next)
- {
- if(id == ptr->id)
- {
- v_head = get_new_value_list(ptr->value_head);
- if(v_head)
- {
- free_value_count(ptr->value_head);
- ptr->value_head = v_head;
- }
- }
- }
- return re_list;
- }
- static void check_multi_choice_answers(SURVEY_LIST *list, RECORD *re_list)
- {
- SURVEY_DATA *ptr;
- for(ptr = list->head; ptr;ptr = ptr->next)
- {
- if(strcmp(ptr->tag_name, "choice") ==0 && strcmp(ptr->steps_bgcolor, "yes") ==0)
- {
- re_list = parse_multi_select_data(re_list, ptr->id);
- }
- }
- }
- int
- set_survey_graph_results( char *survey_fname, char *survey_result_fname, int number_takers)
- {
- SURVEY_LIST *list;
- RECORD *record_list;
- int results_found = 0;
- int bar_graph_count = 0;
-
- list = survey_data_parser(survey_fname); /* shared_survey_xml_parser.c */
- record_list = record_parser(survey_result_fname); /* shared_record_parser.c */
- if(record_list->head)
- {
- check_multi_choice_answers(list, record_list);
- record_list = sort_value_list(record_list);
- set_title_element(list, record_list, number_takers);
- set_bar_graphs(list,record_list, &bar_graph_count);
- set_text_responses(list,record_list, bar_graph_count);
- results_found = 1;
- }
- free_record_list(record_list);
- free_survey_data_list(list);
- return results_found;
- }