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_PM.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_ORANGE,
00024 V_VIOLET,
00025 V_BLACK,
00026 V_GREEN,
00027 V_YELLOW,
00028 V_BROWN,
00029 V_ORANGE,
00030 V_PINK,
00031 V_BLACK,
00032 V_WHITE,
00033 };
00034
00035 enum { DEFAULT_SERIES_COLOR_NUM = 10 };
00036
00037 enum {
00038 LEGEND_SIZE = 11,
00039 LEGEND_X_SPACING = 12,
00040 LEGEND_Y_SPACING = 2,
00041 };
00042
00043 enum { COMMON_OFFSET = 2 };
00044
00045
00046
00047
00048
00049
00051
00052 init_flag = 0;
00053 grapha_bitmap = NULL;
00054 }
00055
00056
00057
00058
00060
00061 deinit();
00062 }
00063
00064
00065
00066
00089
00090 int seriesNum, int *dataNum,
00091 void *dataArray,
00092 char dataTypeFlag,
00093 char transparentFlag,
00094 char valueFlag,
00095 int numFormat, int *seriesColor, int axisColor) {
00096 err_when(seriesNum > DEFAULT_SERIES_COLOR_NUM && !seriesColor);
00097 err_when(seriesNum <= 0);
00098
00099 graph_width = x2 - x1 - 6;
00100
00101 err_when(graph_width < 0);
00102
00103 grapha_x1 = x1;
00104 grapha_y1 = y1;
00105 grapha_x2 = x2;
00106 grapha_y2 = y2;
00107 series_num = seriesNum;
00108 data_num = dataNum;
00109 data_array = dataArray;
00110 data_type_flag = dataTypeFlag;
00111 transparent_flag = transparentFlag;
00112 value_flag = valueFlag;
00113 num_format = numFormat;
00114 series_color = seriesColor ? seriesColor : default_series_color;
00115 axis_color = axisColor;
00116
00117 init_flag = 1;
00118
00119 if(value_flag)
00120 y_label_max_len = font_chartsm.text_width(MAX_LEN_LABEL);
00121 else
00122 y_label_max_len = 0;
00123 set_font(&font_chartsm);
00124
00125 }
00126
00127
00128
00129
00131
00132 if (grapha_bitmap) {
00133 mem_del(grapha_bitmap);
00134 grapha_bitmap = NULL;
00135 }
00136
00137 init_flag = 0;
00138 }
00139
00140
00141
00142
00144
00145 if (!init_flag)
00146 return;
00147
00148 font_ptr = fontPtr;
00149
00150 calc_pos();
00151 }
00152
00153
00154
00155
00160
00161 graph_height = grapha_y2 - grapha_y1 ;
00162 short YLabelWidth = -COMMON_OFFSET;
00163 short XLabelHeight = -COMMON_OFFSET;
00164 series_x1 = grapha_x1 + 4 + COMMON_OFFSET*2;
00165 series_y1 = grapha_y1 + 4 + COMMON_OFFSET*4;
00166 series_x2 = grapha_x2 - 4 - COMMON_OFFSET*2;
00167 series_y2 = grapha_y1 + graph_height - COMMON_OFFSET*2;
00168 }
00169
00170
00171
00172
00174
00175 if (transparent_flag) {
00176 vga.use_back();
00177
00178 user_interface.brighten(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2);
00179 grapha_bitmap = vga_back.save_area(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2, grapha_bitmap);
00180 }
00181
00182 refresh();
00183 }
00184
00185
00186
00187
00189
00190
00191
00192 if (transparent_flag) {
00193 user_interface.rect(grapha_x1, grapha_y1, grapha_x2, grapha_y2, 1);
00194 vga_back.rest_area(grapha_bitmap, 0, 0);
00195 }
00196 else {
00197 user_interface.bar(grapha_x1, grapha_y1, grapha_x2, grapha_y2);
00198 user_interface.panel(grapha_x1+3, grapha_y1+3, grapha_x2-4, grapha_y2-4);
00199 }
00200 draw_scale();
00201 draw_series();
00202
00203
00204
00205
00206
00207 }
00208
00209
00210
00211
00213
00214 double data, maxVal = 0.0;
00215 x_axis_pos = 0;
00216
00217 for (int i = 0; i < series_num * *data_num; i++) {
00218 switch (data_type_flag) {
00219 case DATA_DOUBLE:
00220 data = ((double*)data_array)[i];
00221 break;
00222 case DATA_FLOAT:
00223 data = double(((float*)data_array)[i]);
00224 break;
00225 case DATA_INT:
00226 data = double(((int*)data_array)[i]);
00227 break;
00228 case DATA_LONG:
00229 data = double(((long*)data_array)[i]);
00230 break;
00231 }
00232 if (fabs(data) > maxVal)
00233 maxVal = fabs(data);
00234 if (!x_axis_pos && data < 0.0)
00235 x_axis_pos = 1;
00236 }
00237 if (maxVal>10)
00238 max_scale = maxVal;
00239 else
00240 max_scale = 10;
00241 }
00242
00243
00244
00245
00247
00248 find_scale();
00249
00250
00251 if (x_axis_pos)
00252 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2+COMMON_OFFSET*2, axis_color);
00253 else
00254 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2, axis_color);
00255
00256
00257 int currY;
00258 if (x_axis_pos)
00259 currY = series_y2 - short(((float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00260 else
00261 currY = series_y2;
00262
00263
00264
00265
00266 vga_back.bar(series_x1, currY, series_x2-COMMON_OFFSET, currY+1, axis_color);
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_month_passed;
00294 dataArray+=HISTORY_MONTH_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
00303 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00304 for (int j = 1; j < info.graph_month_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_month_passed;
00333 dataArray+=HISTORY_MONTH_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
00342 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00343 for (int j = 1; j < info.graph_month_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 short prevX, prevY, currX, currY;
00369
00370 for (int i = 0; i < series_num; i++) {
00371 dataArray-=info.graph_month_passed;
00372 dataArray+=HISTORY_MONTH_COUNT;
00373 prevX = series_x1;
00374 if (x_axis_pos)
00375 prevY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00376 else
00377 prevY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00378
00379 dataArray++;
00380
00381 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00382 for (int j = 1; j < info.graph_month_passed; j++) {
00383 currX = series_x1 + (int)(x_axis_step*j);
00384 if (x_axis_pos)
00385 currY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00386 else
00387 currY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00388
00389 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00390
00391 prevX = currX;
00392 prevY = currY;
00393 dataArray++;
00394 }
00395
00396 if (value_flag)
00397 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);
00398 }
00399 }
00400
00401
00402
00403
00405
00406 long *dataArray = (long *) data_array;
00407 short prevX, prevY, currX, currY;
00408
00409 for (int i = 0; i < series_num; i++) {
00410 dataArray-=info.graph_month_passed;
00411 dataArray+=HISTORY_MONTH_COUNT;
00412 prevX = series_x1;
00413 if (x_axis_pos)
00414 prevY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00415 else
00416 prevY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00417
00418 dataArray++;
00419
00420 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00421 for (int j = 1; j < info.graph_month_passed; j++) {
00422 currX = series_x1 + (int)(x_axis_step*j);
00423 if (x_axis_pos)
00424 currY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00425 else
00426 currY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00427
00428 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00429
00430 prevX = currX;
00431 prevY = currY;
00432 dataArray++;
00433 }
00434
00435 if (value_flag)
00436 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);
00437 }
00438 }
00439
00440
00441
00442
00444
00445 char *valueString;
00446 switch (data_type_flag) {
00447 case DATA_FLOAT:
00448 valueString = m.format(*((float *) value), num_format); break;
00449 case DATA_DOUBLE:
00450 valueString = m.format(*((double *) value), num_format); break;
00451 case DATA_INT:
00452 valueString = m.format(*((int *) value), num_format); break;
00453 case DATA_LONG:
00454 valueString = m.format(*((long *) value), num_format); break;
00455 }
00456
00457 short textHeight = font_ptr->max_font_height;
00458 short textWidth = font_ptr->text_width(valueString) + 1;
00459
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