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_PY.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
00088
00089 int seriesNum, int *dataNum,
00090 void *dataArray,
00091 char dataTypeFlag,
00092 char transparentFlag,
00093 char valueFlag,
00094 int numFormat, int *seriesColor, int axisColor) {
00095 err_when(seriesNum > DEFAULT_SERIES_COLOR_NUM && !seriesColor);
00096 err_when(seriesNum <= 0);
00097
00098 graph_width = x2 - x1 - 6;
00099
00100 err_when(graph_width < 0);
00101
00102 grapha_x1 = x1;
00103 grapha_y1 = y1;
00104 grapha_x2 = x2;
00105 grapha_y2 = y2;
00106 series_num = seriesNum;
00107 data_num = dataNum;
00108 data_array = dataArray;
00109 data_type_flag = dataTypeFlag;
00110 transparent_flag = transparentFlag;
00111 value_flag = valueFlag;
00112 num_format = numFormat;
00113 series_color = seriesColor ? seriesColor : default_series_color;
00114 axis_color = axisColor;
00115
00116 init_flag = 1;
00117
00118 if(value_flag)
00119 y_label_max_len = font_chartsm.text_width(MAX_LEN_LABEL);
00120 else
00121 y_label_max_len = 0;
00122 set_font(&font_chartsm);
00123
00124 }
00125
00126
00127
00128
00130
00131 if (grapha_bitmap) {
00132 mem_del(grapha_bitmap);
00133 grapha_bitmap = NULL;
00134 }
00135
00136 init_flag = 0;
00137 }
00138
00139
00140
00141
00143
00144 if (!init_flag)
00145 return;
00146
00147 font_ptr = fontPtr;
00148
00149 calc_pos();
00150 }
00151
00152
00153
00154
00159
00160 graph_height = grapha_y2 - grapha_y1 ;
00161 short YLabelWidth = -COMMON_OFFSET;
00162 short XLabelHeight = -COMMON_OFFSET;
00163 series_x1 = grapha_x1 + 4 + COMMON_OFFSET*2;
00164 series_y1 = grapha_y1 + 4 + COMMON_OFFSET*4;
00165 series_x2 = grapha_x2 - 4 - COMMON_OFFSET*2;
00166 series_y2 = grapha_y1 + graph_height - COMMON_OFFSET*2;
00167 }
00168
00169
00170
00171
00173
00174 if (transparent_flag) {
00175 vga.use_back();
00176
00177 user_interface.brighten(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2);
00178 grapha_bitmap = vga_back.save_area(grapha_x1+4, grapha_y1+4, grapha_x2-2, grapha_y2-2, grapha_bitmap);
00179 }
00180
00181 refresh();
00182 }
00183
00184
00185
00186
00188
00189
00190
00191 if (transparent_flag) {
00192 user_interface.rect(grapha_x1, grapha_y1, grapha_x2, grapha_y2, 1);
00193 vga_back.rest_area(grapha_bitmap, 0, 0);
00194 }
00195 else {
00196 user_interface.bar(grapha_x1, grapha_y1, grapha_x2, grapha_y2);
00197 user_interface.panel(grapha_x1+3, grapha_y1+3, grapha_x2-4, grapha_y2-4);
00198 }
00199 draw_scale();
00200 draw_series();
00201
00202
00203
00204
00205
00206 }
00207
00208
00209
00210
00212
00213 double data, maxVal = 0.0;
00214 x_axis_pos = 0;
00215
00216 for (int i = 0; i < series_num * *data_num; i++) {
00217 switch (data_type_flag) {
00218 case DATA_DOUBLE:
00219 data = ((double*)data_array)[i];
00220 break;
00221 case DATA_FLOAT:
00222 data = double(((float*)data_array)[i]);
00223 break;
00224 case DATA_INT:
00225 data = double(((int*)data_array)[i]);
00226 break;
00227 case DATA_LONG:
00228 data = double(((long*)data_array)[i]);
00229 break;
00230 }
00231 if (fabs(data) > maxVal)
00232 maxVal = fabs(data);
00233 if (!x_axis_pos && data < 0.0)
00234 x_axis_pos = 1;
00235 }
00236 if (maxVal>10)
00237 max_scale = maxVal;
00238 else
00239 max_scale = 10;
00240 }
00241
00242
00243
00244
00246
00247 find_scale();
00248
00249
00250 if (x_axis_pos)
00251 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2+COMMON_OFFSET*2, axis_color);
00252 else
00253 vga_back.bar(series_x1, series_y1-COMMON_OFFSET*2, series_x1+1, series_y2, axis_color);
00254
00255
00256 int currY;
00257 if (x_axis_pos)
00258 currY = series_y2 - short(((float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00259 else
00260 currY = series_y2;
00261
00262
00263
00264
00265 vga_back.bar(series_x1, currY, series_x2-COMMON_OFFSET, currY+1, axis_color);
00266
00267 x_axis_step = (double)(series_x2-series_x1) / (*data_num-1);
00268 }
00269
00270
00271
00272
00274
00275 switch (data_type_flag) {
00276 case DATA_FLOAT: draw_series_float(); break;
00277 case DATA_DOUBLE: draw_series_double(); break;
00278 case DATA_INT: draw_series_int(); break;
00279 case DATA_LONG: draw_series_long(); break;
00280 }
00281 }
00282
00283
00284
00285
00287
00288 float *dataArray = (float *) data_array;
00289 short prevX, prevY, currX, currY;
00290
00291 for (int i = 0; i < series_num; i++) {
00292 dataArray-=info.graph_year_passed;
00293 dataArray+=HISTORY_YEAR_COUNT;
00294 prevX = series_x1;
00295 if (x_axis_pos)
00296 prevY = series_y2 - short(((*dataArray+float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00297 else
00298 prevY = series_y2 - short(*dataArray * float(series_y2-series_y1) / float(max_scale));
00299
00300 dataArray++;
00301 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00302
00303 for (int j = 1; j < info.graph_year_passed; j++) {
00304 currX = series_x1 + (int)(x_axis_step*j);
00305 if (x_axis_pos)
00306 currY = series_y2 - short(((*dataArray+float(max_scale)) * float(series_y2-series_y1) / float(max_scale*2)));
00307 else
00308 currY = series_y2 - short(*dataArray * float(series_y2-series_y1) / float(max_scale));
00309
00310 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00311
00312 prevX = currX;
00313 prevY = currY;
00314 dataArray++;
00315 }
00316
00317 if (value_flag)
00318 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);
00319 }
00320 }
00321
00322
00323
00324
00326
00327 double *dataArray = (double *) data_array;
00328 short prevX, prevY, currX, currY;
00329
00330 for (int i = 0; i < series_num; i++) {
00331 dataArray-=info.graph_year_passed;
00332 dataArray+=HISTORY_YEAR_COUNT;
00333 prevX = series_x1;
00334 if (x_axis_pos)
00335 prevY = series_y2 - short(((*dataArray+max_scale) * double(series_y2-series_y1) / (max_scale*2)));
00336 else
00337 prevY = series_y2 - short(*dataArray * double(series_y2-series_y1) / max_scale);
00338
00339 dataArray++;
00340 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00341
00342 for (int j = 1; j < info.graph_year_passed; j++) {
00343 currX = series_x1 + (int)(x_axis_step*j);
00344 if (x_axis_pos)
00345 currY = series_y2 - short(((*dataArray+max_scale) * double(series_y2-series_y1) / (max_scale*2)));
00346 else
00347 currY = series_y2 - short(*dataArray * double(series_y2-series_y1) / max_scale);
00348
00349 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00350
00351 prevX = currX;
00352 prevY = currY;
00353 dataArray++;
00354 }
00355
00356 if (value_flag)
00357 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);
00358 }
00359 }
00360
00361
00362
00363
00365
00366 int *dataArray = (int *) data_array;
00367 short prevX, prevY, currX, currY;
00368
00369 for (int i = 0; i < series_num; i++) {
00370 dataArray-=info.graph_year_passed;
00371 dataArray+=HISTORY_YEAR_COUNT;
00372 prevX = series_x1;
00373 if (x_axis_pos)
00374 prevY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00375 else
00376 prevY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00377
00378 dataArray++;
00379 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00380
00381 for (int j = 1; j < info.graph_year_passed; j++) {
00382 currX = series_x1 + (int)(x_axis_step*j);
00383 if (x_axis_pos)
00384 currY = series_y2 - ((*dataArray+int(max_scale)) * (series_y2-series_y1) / int(max_scale*2));
00385 else
00386 currY = series_y2 - *dataArray * (series_y2-series_y1) / int(max_scale);
00387
00388 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00389
00390 prevX = currX;
00391 prevY = currY;
00392 dataArray++;
00393 }
00394
00395 if (value_flag)
00396 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);
00397 }
00398 }
00399
00400
00401
00402
00404
00405 long *dataArray = (long *) data_array;
00406 short prevX, prevY, currX, currY;
00407
00408 for (int i = 0; i < series_num; i++) {
00409 dataArray-=info.graph_year_passed;
00410 dataArray+=HISTORY_YEAR_COUNT;
00411 prevX = series_x1;
00412 if (x_axis_pos)
00413 prevY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00414 else
00415 prevY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00416
00417 dataArray++;
00418 vga_back.thick_line(prevX-1, prevY, prevX+1, prevY, vga_back.translate_color(series_color[i]));
00419
00420 for (int j = 1; j < info.graph_year_passed; j++) {
00421 currX = series_x1 + (int)(x_axis_step*j);
00422 if (x_axis_pos)
00423 currY = series_y2 - short(((*dataArray+long(max_scale)) * long(series_y2-series_y1) / long(max_scale*2)));
00424 else
00425 currY = series_y2 - short(*dataArray * long(series_y2-series_y1) / long(max_scale));
00426
00427 vga_back.thick_line(prevX, prevY, currX, currY, vga_back.translate_color(series_color[i]));
00428
00429 prevX = currX;
00430 prevY = currY;
00431 dataArray++;
00432 }
00433
00434 if (value_flag)
00435 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);
00436 }
00437 }
00438
00439
00440
00441
00443
00444 char *valueString;
00445 switch (data_type_flag) {
00446 case DATA_FLOAT:
00447 valueString = m.format(*((float *) value), num_format); break;
00448 case DATA_DOUBLE:
00449 valueString = m.format(*((double *) value), num_format); break;
00450 case DATA_INT:
00451 valueString = m.format(*((int *) value), num_format); break;
00452 case DATA_LONG:
00453 valueString = m.format(*((long *) value), num_format); break;
00454 }
00455
00456 short textHeight = font_ptr->max_font_height;
00457 short textWidth = font_ptr->text_width(valueString) + 1;
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 font_chartsm.put(x+3,y,valueString);
00478 }
00479
00480