00001
00002
00003
00004
00005 #include <ALL.H>
00006 #include <COLOR.H>
00007 #include <OINFO.H>
00008 #include <OVGA.H>
00009 #include <OSYS.H>
00010 #include <OFONT.H>
00011 #include <OMOUSE.H>
00012 #include <OGRPH_PT.H>
00013 #include <OIFACE.H>
00014
00015 #include <math.h>
00016
00017
00018
00019 #define MAX_LEN_LABEL "0%"
00020
00021 static int default_series_color[] = {
00022 V_BLUE,
00023 V_GREEN,
00024 V_RED,
00025 V_YELLOW,
00026 V_VIOLET,
00027 V_BROWN,
00028 V_ORANGE,
00029 V_PINK,
00030 V_BLACK,
00031 V_WHITE,
00032 };
00033
00034 enum { DEFAULT_SERIES_COLOR_NUM = 10 };
00035
00036 enum {
00037 LEGEND_SIZE = 11,
00038 LEGEND_X_SPACING = 12,
00039 LEGEND_Y_SPACING = 2,
00040 };
00041
00042 enum { COMMON_OFFSET = 2 };
00043
00044
00045
00046
00047
00048
00050
00051 init_flag = 0;
00052 grapha_bitmap = NULL;
00053 }
00054
00055
00056
00057
00059
00060 deinit();
00061 }
00062
00063
00064
00065
00094
00095 int seriesNum, int *dataNum,
00096 void *dataArray,
00097 char dataTypeFlag,
00098 char transparentFlag,
00099 char valueFlag,
00100 int numFormat, double defaultUpperBound, int *seriesColor, int axisColor
00101 ) {
00102 err_when(seriesNum > DEFAULT_SERIES_COLOR_NUM && !seriesColor);
00103 err_when(seriesNum <= 0);
00104
00105 graph_width = x2 - x1 - 6;
00106
00107 err_when(graph_width < 0);
00108
00109 grapha_x1 = x1;
00110 grapha_y1 = y1;
00111 grapha_x2 = x2;
00112 grapha_y2 = y2;
00113 series_num = seriesNum;
00114 data_num = dataNum;
00115 data_array = dataArray;
00116 data_type_flag = dataTypeFlag;
00117 transparent_flag = transparentFlag;
00118 value_flag = valueFlag;
00119 num_format = numFormat;
00120 series_color = seriesColor ? seriesColor : default_series_color;
00121 axis_color = axisColor;
00122 default_upper_bound = defaultUpperBound;
00123
00124 init_flag = 1;
00125
00126 if(value_flag)
00127 y_label_max_len = font_chartsm.text_width(MAX_LEN_LABEL);
00128 else
00129 y_label_max_len = 0;
00130 set_font(&font_chartsm);
00131
00132 }
00133
00134
00135
00136
00138
00139 if (grapha_bitmap) {
00140 mem_del(grapha_bitmap);
00141 grapha_bitmap = NULL;
00142 }
00143 init_flag = 0;
00144 }
00145
00146
00147
00148
00150
00151 if (!init_flag)
00152 return;
00153
00154 font_ptr = fontPtr;
00155
00156 calc_pos();
00157 }
00158
00159
00160
00161
00166
00167 graph_height = grapha_y2 - grapha_y1 ;
00168 short YLabelWidth = -COMMON_OFFSET;
00169 short XLabelHeight = -COMMON_OFFSET;
00170 series_x1 = grapha_x1 + 4 + COMMON_OFFSET*2;
00171 series_y1 = grapha_y1 + 4 + COMMON_OFFSET*4;
00172 series_x2 = grapha_x2 - 4 - COMMON_OFFSET*2;
00173 series_y2 = grapha_y1 + graph_height - COMMON_OFFSET*2;
00174 }
00175
00176
00177
00178
00180
00181 if (transparent_flag) {
00182 vga.use_back();
00183
00184 user_interface.brighten(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2);
00185 grapha_bitmap = vga_back.save_area(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2, grapha_bitmap);
00186 }
00187
00188 refresh();
00189 }
00190
00191
00192
00193
00195
00196
00197
00198 if (transparent_flag) {
00199 user_interface.rect(grapha_x1, grapha_y1, grapha_x2, grapha_y2, 1);
00200 vga_back.rest_area(grapha_bitmap, 0, 0);
00201 }
00202 else {
00203 user_interface.bar(grapha_x1, grapha_y1, grapha_x2, grapha_y2);
00204 user_interface.panel(grapha_x1+3, grapha_y1+3, grapha_x2-4, grapha_y2-4);
00205 }
00206 draw_scale();
00207 draw_series();
00208
00209
00210
00211
00212
00213 }
00214
00215
00216
00217
00219
00220 double data, maxVal = 0.0;
00221 x_axis_pos = 0;
00222
00223 for (int i = 0; i < series_num * *data_num; i++) {
00224 switch (data_type_flag) {
00225 case DATA_DOUBLE:
00226 data = ((double*)data_array)[i];
00227 break;
00228 case DATA_FLOAT:
00229 data = double(((float*)data_array)[i]);
00230 break;
00231 case DATA_INT:
00232 data = double(((int*)data_array)[i]);
00233 break;
00234 case DATA_LONG:
00235 data = double(((long*)data_array)[i]);
00236 break;
00237 }
00238 if (fabs(data) > maxVal)
00239 maxVal = fabs(data);
00240 if (!x_axis_pos && data < 0.0)
00241 x_axis_pos = 1;
00242 }
00243 if (maxVal > default_upper_bound)
00244 max_scale = maxVal;
00245 else
00246 max_scale = default_upper_bound;
00247 }
00248
00249
00250
00251
00253
00254 find_scale();
00255
00256
00257 if (x_axis_pos)
00258 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2+COMMON_OFFSET*2, axis_color);
00259 else
00260 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2, axis_color);
00261
00262 if (x_axis_pos)
00263 vga_back.bar(series_x1, series_y2+COMMON_OFFSET*2, series_x2-COMMON_OFFSET, series_y2+COMMON_OFFSET*2, axis_color);
00264 else
00265 vga_back.bar(series_x1, series_y2, series_x2-COMMON_OFFSET, series_y2, axis_color);
00266
00267
00268 x_axis_step = (double)(series_x2-series_x1) / (*data_num-1);
00269 }
00270
00271
00272
00273
00275
00276 switch (data_type_flag) {
00277 case DATA_FLOAT: draw_series_float(); break;
00278 case DATA_DOUBLE: draw_series_double(); break;
00279 case DATA_INT: draw_series_int(); break;
00280 case DATA_LONG: draw_series_long(); break;
00281 }
00282 }
00283
00284
00285
00286
00288
00289 float *dataArray = (float *) data_array;
00290 short prevX, prevY, currX, currY;
00291
00292 for (int i = 0; i < series_num; i++) {
00293 dataArray-=info.graph_trimester_passed;
00294 dataArray+=HISTORY_TRIMESTER_COUNT;
00295 prevX = series_x1;
00296 if (x_axis_pos)
00297 prevY = series_y2 - short(((*dataArray+float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00298 else
00299 prevY = series_y2 - short(*dataArray * float(series_y2-series_y1) / float(max_scale));
00300
00301 dataArray++;
00302 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00303
00304 for (int j = 1; j < info.graph_trimester_passed; j++) {
00305 currX = series_x1 + (int)(x_axis_step*j);
00306 if (x_axis_pos)
00307 currY = series_y2 - short(((*dataArray+float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00308 else
00309 currY = series_y2 - short(*dataArray * float(series_y2-series_y1) / float(max_scale));
00310
00311 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00312
00313 prevX = currX;
00314 prevY = currY;
00315 dataArray++;
00316 }
00317
00318 if (value_flag)
00319 draw_value(dataArray-1, vga_back.translate_color(V_BLACK), prevX+COMMON_OFFSET-(int)(0.3f*x_axis_step), prevY-font_ptr->max_font_height/2, DATA_FLOAT);
00320 }
00321 }
00322
00323
00324
00325
00327
00328 double *dataArray = (double *) data_array;
00329 short prevX, prevY, currX, currY;
00330
00331 for (int i = 0; i < series_num; i++) {
00332 dataArray-=info.graph_trimester_passed;
00333 dataArray+=HISTORY_TRIMESTER_COUNT;
00334 prevX = series_x1;
00335 if (x_axis_pos)
00336 prevY = series_y2 - short(((*dataArray+max_scale) * double(series_y2-series_y1) / (max_scale*2)));
00337 else
00338 prevY = series_y2 - short(*dataArray * double(series_y2-series_y1) / max_scale);
00339
00340 dataArray++;
00341 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00342
00343 for (int j = 1; j < info.graph_trimester_passed; j++) {
00344 currX = series_x1 + (int)(x_axis_step*j);
00345 if (x_axis_pos)
00346 currY = series_y2 - short(((*dataArray+max_scale) * double(series_y2-series_y1) / (max_scale*2)));
00347 else
00348 currY = series_y2 - short(*dataArray * double(series_y2-series_y1) / max_scale);
00349
00350 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00351
00352 prevX = currX;
00353 prevY = currY;
00354 dataArray++;
00355 }
00356
00357 if (value_flag)
00358 draw_value(dataArray-1, vga_back.translate_color(V_BLACK), prevX+COMMON_OFFSET-(int)(0.3f*x_axis_step), prevY-font_ptr->max_font_height/2, DATA_DOUBLE);
00359 }
00360 }
00361
00362
00363
00364
00366
00367 int *dataArray = (int *) data_array;
00368
00369 short prevX, prevY, currX, currY;
00370
00371 for (int i = 0; i < series_num; i++) {
00372 dataArray-=info.graph_trimester_passed;
00373 dataArray+=HISTORY_TRIMESTER_COUNT;
00374 prevX = series_x1;
00375 if (x_axis_pos)
00376 prevY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00377 else
00378 prevY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00379
00380 dataArray++;
00381 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00382
00383 for (int j = 1; j < info.graph_trimester_passed; j++) {
00384 currX = series_x1 + (int)(x_axis_step*j);
00385 if (x_axis_pos)
00386 currY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00387 else
00388 currY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00389
00390 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00391
00392 prevX = currX;
00393 prevY = currY;
00394 dataArray++;
00395 }
00396
00397 if (value_flag)
00398 draw_value(dataArray-1, vga_back.translate_color(V_BLACK), prevX+COMMON_OFFSET-(int)(0.3f*x_axis_step), prevY-font_ptr->max_font_height/2, DATA_INT);
00399 }
00400 }
00401
00402
00403
00404
00406
00407 long *dataArray = (long *) data_array;
00408 short prevX, prevY, currX, currY;
00409
00410 for (int i = 0; i < series_num; i++) {
00411 dataArray-=info.graph_trimester_passed;
00412 dataArray+=HISTORY_TRIMESTER_COUNT;
00413 prevX = series_x1;
00414 if (x_axis_pos)
00415 prevY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00416 else
00417 prevY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00418
00419 dataArray++;
00420 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00421
00422 for (int j = 1; j < info.graph_trimester_passed; j++) {
00423 currX = series_x1 + (int)(x_axis_step*j);
00424 if (x_axis_pos)
00425 currY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00426 else
00427 currY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00428
00429 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00430
00431 prevX = currX;
00432 prevY = currY;
00433 dataArray++;
00434 }
00435
00436 if (value_flag)
00437 draw_value(dataArray-1, vga_back.translate_color(V_BLACK), prevX+COMMON_OFFSET-(int)(0.3f*x_axis_step), prevY-font_ptr->max_font_height/2, DATA_LONG);
00438 }
00439 }
00440
00441
00442
00443
00445
00446 char *valueString;
00447 switch (data_type_flag) {
00448 case DATA_FLOAT:
00449 valueString = m.format(*((float *) value), num_format); break;
00450 case DATA_DOUBLE:
00451 valueString = m.format(*((double *) value), num_format); break;
00452 case DATA_INT:
00453 valueString = m.format(*((int *) value), num_format); break;
00454 case DATA_LONG:
00455 valueString = m.format(*((long *) value), num_format); break;
00456 }
00457
00458 short textHeight = font_ptr->max_font_height;
00459 short textWidth = font_ptr->text_width(valueString) + 1;
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 font_chartsm.put(x+3,y,valueString);
00480 }
00481
00482