📄 blib_graph.c
字号:
// commands prefix while ( strchr("BbNn", *p) ) { if ( *p == 'B' || *p == 'b' ) { // do not draw draw = 0; p ++; } else draw = 1; if ( *p == 'N' || *p == 'n' ) { // do not update the position update = 0; p ++; } else update = 1; } // commands switch ( *p ) { case 'U': case 'u': // up p = draw_getval(p, &y); if ( draw ) dev_line(gra_x, gra_y, gra_x, gra_y - y); if ( update ) gra_y -= y; continue; case 'D': case 'd': // down p = draw_getval(p, &y); if ( draw ) dev_line(gra_x, gra_y, gra_x, gra_y + y); if ( update ) gra_y += y; continue; case 'L': case 'l': // left p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x - x, gra_y); if ( update ) gra_x -= x; continue; case 'R': case 'r': // right p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x + x, gra_y); if ( update ) gra_x += x; continue; case 'E': case 'e': // up & right p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x + x, gra_y - x); if ( update ) { gra_x += x; gra_y -= x; } continue; case 'F': case 'f': // down & right p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x + x, gra_y + x); if ( update ) { gra_x += x; gra_y += x; } continue; case 'G': case 'g': // down & left p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x - x, gra_y + x); if ( update ) { gra_x -= x; gra_y += x; } continue; case 'H': case 'h': // up & left p = draw_getval(p, &x); if ( draw ) dev_line(gra_x, gra_y, gra_x - x, gra_y - x); if ( update ) { gra_x -= x; gra_y -= x; } continue; case 'M': case 'm': // move to x, y if ( *(p+1) == '-' ) { // relative r = -1; p ++; } if ( *(p+1) == '+' ) { // relative r = 1; p ++; } else r = 0; // absolute p = draw_getval(p, &x); if ( *p != ',' ) { rt_raise("DRAW: MISSING ,"); v_free(&var); return; } else p ++; p = draw_getval(p, &y); if ( r ) { if ( draw ) dev_line(gra_x, gra_y, gra_x + x * r, gra_y + y * r); if ( update ) { gra_x += x * r; gra_y += x * r; } } else { if ( draw ) dev_line(gra_x, gra_y, x, y); if ( update ) { gra_x = x; gra_y = y; } } continue; case 'C': case 'c': // color p = draw_getval(p, &x); dev_setcolor(x); continue; default: rt_raise("DRAW: '%c' UNSUPPORTED", *p); v_free(&var); return; } p ++; } dev_setcolor(prev_color); v_free(&var);}//// CHART chart-type, v() [, mark-type [, x1, y1, x2, y2]]//// chart-type// 1 = line-chart// 2 = bar-chart//// mark-type (bit-mask)// 0 = none// 1 = labels// 2 = ruler//void cmd_chart_fstr(double v, char *buf){ if ( fabs(v) >= 10000000000.0 ) { ftostr(v / 1000000000.0, buf); if ( buf[3] == '.' ) buf[3] = '\0'; else buf[4] = '\0'; strcat(buf, "G"); } else if ( fabs(v) >= 10000000.0 ) { ftostr(v / 1000000.0, buf); if ( buf[3] == '.' ) buf[3] = '\0'; else buf[4] = '\0'; strcat(buf, "M"); } else if ( fabs(v) >= 10000.0 ) { ftostr(v / 1000.0, buf); if ( buf[3] == '.' ) buf[3] = '\0'; else buf[4] = '\0'; strcat(buf, "K"); } else { ftostr(v, buf); buf[5] = '\0'; }}void cmd_chart(){ var_t *var_p, *elem_p; int i, count; double *vals; double vmin, vmax, lx, ly; int dx, dy, color = 0; int *pts; char buf[32]; int prev_fgcolor = dev_fgcolor; int prev_bgcolor = dev_bgcolor; // parameters int chart = 0, marks = 0; int x1 = 0, y1 = 0, x2 = os_graf_mx, y2 = os_graf_my; int rx1 = 0, ry2; // chart type chart = par_getint(); if ( prog_error ) return; par_getcomma(); if ( prog_error ) return; // array if ( !code_isnullarray() ) { err_typemismatch(); return; } code_skipnext(); var_p = tvar[code_getnext16()]; count = var_p->size; // optional labels-flag if ( code_peek() == kwTYPE_SEP ) { par_getcomma(); if ( prog_error ) return; marks = par_getint(); if ( prog_error ) return; // optional x1,y1,x2,y2 if ( code_peek() == kwTYPE_SEP ) { par_getcomma(); if ( prog_error ) return; rx1 = x1 = par_getint(); if ( prog_error ) return; par_getcomma(); if ( prog_error ) return; y1 = par_getint(); if ( prog_error ) return; par_getcomma(); if ( prog_error ) return; x2 = par_getint(); if ( prog_error ) return; par_getcomma(); if ( prog_error ) return; ry2 = y2 = par_getint(); if ( prog_error ) return; } } // get array's values vals = (double *) tmp_alloc(sizeof(double) * count); for ( i = 0; i < count; i ++ ) { elem_p = v_getelemptr(var_p, i); if ( prog_error ) { tmp_free(vals); return; } switch ( elem_p->type ) { case V_INT: vals[i] = elem_p->i; break; case V_NUM: vals[i] = elem_p->n; break; case V_STR: vals[i] = v_getval(elem_p); break; default: err_typemismatch(); tmp_free(vals); return; } } // ready dev_settextcolor(0, 15); pts = (int *) tmp_alloc(sizeof(int) * count * 2); if ( marks & 0x2 ) { // ruler x1 += dev_textwidth("00000") + 1; y2 -= (dev_textheight("0") + 1); } if ( marks & 0x1 ) { if ( chart == 1 ) { // line x1 += 2; x2 -= 2; y1 += 2; y2 -= 2; } } dx = (x2-x1); dy = (y2-y1); // limits vmin = vmax = vals[0]; for ( i = 1; i < count; i ++ ) { if ( vmin > vals[i] ) vmin = vals[i]; if ( vmax < vals[i] ) vmax = vals[i]; } if ( chart == 1 ) // line-chart lx = ((double) dx) / (double) (count-1); else lx = ((double) dx) / (double) count; ly = ((double) dy) / (vmax-vmin); // calc points for ( i = 0; i < count; i ++ ) { pts[i*2] = x1 + i*lx; pts[i*2+1] = y1 + (dy - ((vals[i]-vmin)*ly)); } // draw ruler if ( marks & 0x2 ) { int fh, fw, n, y, x; double v; // vertical fh = dev_textheight("0"); n = dy / (fh * 1.5); if ( (n - 1) > 0 ) { for ( i = 0; i <= n; i ++ ) { if ( i == 0 ) v = vmin; else if ( i == n ) v = vmax; else v = vmin + ( ((double) i+1) * ((vmax-vmin)/ (double)(n+1)) ); cmd_chart_fstr(v, buf); y = y1 + (dy - ((v-vmin)*ly)); if ( i != 0 ) dev_setxy(rx1+1, y+1); else dev_setxy(rx1+1, y-fh); dev_print(buf); dev_line(x1-4, y, x1, y); } } // horizontal fw = dev_textwidth("000"); n = -1; if ( count <= 24 ) { if ( count * (fw * 1.34) < dx ) n = count; } if ( n == -1 ) n = dx / (fw * 1.5); if ( (n - 1) > 0 ) { for ( i = 0; i < n; i ++ ) { if ( i == 0 ) v = 0; else v = i * ((double) count/ (double)n); ftostr(v+var_p->lbound[0], buf); buf[3] = '\0'; fw = dev_textwidth(buf); x = x1 + v*lx; if ( chart == 1 ) dev_setxy(x-fw, y2+1); else { if ( x+fw+1 < x2 ) dev_setxy(x+1, y2+1); } dev_print(buf); dev_line(x, y2, x, y2+4); } } dev_line(x1, y1, x1, y2); dev_line(x1, y2, x2, y2); x1 ++; y2 --; dx = (x2-x1); dy = (y2-y1); } // draw switch ( chart ) { case 1: // line chart // draw line for ( i = 1; i < count; i ++ ) dev_line(pts[(i-1)*2], pts[(i-1)*2+1], pts[i*2], pts[i*2+1]); // draw marks if ( marks & 0x1 ) { for ( i = 0; i < count; i ++ ) { int mx, my; int fh, fw; cmd_chart_fstr(vals[i], buf); fw = dev_textwidth(buf); fh = dev_textheight(buf); mx = pts[i*2] - fw/2; my = pts[i*2+1]; if ( my > (y1+(y2-y1)/2) ) my -= fh; if ( mx <= x1 ) mx = x1+1; if ( mx+fw >= x2 ) mx = x2-fw; dev_setxy(mx, my); dev_print(buf); dev_rect(pts[i*2]-2, pts[i*2+1]-2, pts[i*2]+2, pts[i*2+1]+2, 1); } } break; case 2: // bar chart // draw rect color = 0; for ( i = 1; i < count; i ++ ) { if ( os_color_depth > 2 ) { dev_setcolor(color); color ++; if ( color >= 15 ) color = 0; } dev_rect(pts[(i-1)*2], pts[(i-1)*2+1], pts[i*2]-2, y2, 1); } if ( os_color_depth > 2 ) dev_setcolor(color); dev_rect( pts[(count-1)*2], pts[(count-1)*2+1], pts[(count-1)*2]+lx-1, y2, 1); // draw marks if ( marks & 0x1 ) { color = 0; for ( i = 0; i < count; i ++ ) { int mx, my; int fh, fw; cmd_chart_fstr(vals[i], buf); fw = dev_textwidth(buf); fh = dev_textheight(buf); mx = pts[i*2] + lx/2-fw/2; my = pts[i*2+1]; if ( os_color_depth > 2 ) { if ( my-fh >= y1 ) dev_settextcolor(0, 15); else { if ( color >= 7 && color != 8 ) dev_settextcolor(0, color); else dev_settextcolor(15, color); } color ++; if ( color >= 15 ) color = 0; } if ( my-fh >= y1 ) my -= fh; if ( mx <= x1 ) mx = x1 + 1; if ( mx+fw >= x2 ) mx = x2 - fw; dev_setxy(mx, my); dev_print(buf); } } break; }; // tmp_free(pts); tmp_free(vals); dev_settextcolor(prev_fgcolor, prev_bgcolor);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -