/* * IupPPlot Test * Description : Create all built-in plots. * It is organised as two side-by-side panels: * - left panel for current plot control * - right panel containg tabbed plots * Remark : depend on libs IUP, CD, IUP_PPLOT */ #include #include #include #include #include "iup.h" #include "iupcontrols.h" #include "iup_pplot.h" #include #include #include #include #define MAXPLOT 6 /* room for examples */ static Ihandle *plot[MAXPLOT] = {NULL}; /* PPlot controls */ static Ihandle *dial1, *dial2, /* dials for zooming */ *tgg1, *tgg2, /* autoscale on|off toggles */ *tgg3, *tgg4, /* grid show|hide toggles */ *tgg5, /* legend show|hide toggle */ *tabs; /* tabbed control */ static int delete_cb(Ihandle* ih, int index, int sample_index, float x, float y) { printf("DELETE_CB(%d, %d, %g, %g)\n", index, sample_index, x, y); return IUP_DEFAULT; } static int select_cb(Ihandle* ih, int index, int sample_index, float x, float y, int select) { printf("SELECT_CB(%d, %d, %g, %g, %d)\n", index, sample_index, x, y, select); return IUP_DEFAULT; } static int edit_cb(Ihandle* ih, int index, int sample_index, float x, float y, float *new_x, float *new_y) { printf("EDIT_CB(%d, %d, %g, %g, %g, %g)\n", index, sample_index, x, y, *new_x, *new_y); return IUP_DEFAULT; } static int postdraw_cb(Ihandle* ih, cdCanvas* cnv) { int ix, iy; IupPPlotTransform(ih, 0.003f, 0.02f, &ix, &iy); cdCanvasFont(cnv, NULL, CD_BOLD, 10); cdCanvasTextAlignment(cnv, CD_SOUTH); cdCanvasText(cnv, ix, iy, "My Inline Legend"); printf("POSTDRAW_CB()\n"); return IUP_DEFAULT; } static int predraw_cb(Ihandle* ih, cdCanvas* cnv) { printf("PREDRAW_CB()\n"); return IUP_DEFAULT; } static void InitPlots(void) { int theI; float x, y, theFac; /* PLOT 0 - MakeExamplePlot1 */ IupSetAttribute(plot[0], "TITLE", "AutoScale"); IupSetAttribute(plot[0], "MARGINTOP", "40"); IupSetAttribute(plot[0], "MARGINLEFT", "40"); IupSetAttribute(plot[0], "MARGINBOTTOM", "50"); IupSetAttribute(plot[0], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[0], "LEGENDSHOW", "YES"); IupSetAttribute(plot[0], "AXS_XLABEL", "gnu (Foo)"); IupSetAttribute(plot[0], "AXS_YLABEL", "Space (m^3)"); IupSetAttribute(plot[0], "AXS_YFONTSIZE", "8"); IupSetAttribute(plot[0], "AXS_YTICKFONTSIZE", "8"); IupSetAttribute(plot[0], "AXS_XFONTSIZE", "10"); IupSetAttribute(plot[0], "AXS_YFONTSIZE", "10"); IupSetAttribute(plot[0], "AXS_XLABELCENTERED", "NO"); IupSetAttribute(plot[0], "AXS_YLABELCENTERED", "NO"); // IupSetAttribute(plot[0], "USE_IMAGERGB", "YES"); // IupSetAttribute(plot[0], "USE_GDI+", "YES"); theFac = (float)1.0/(100*100*100); IupPPlotBegin(plot[0], 0); for (theI=-100; theI<=100; theI++) { x = (float)(theI+50); y = theFac*theI*theI*theI; IupPPlotAdd(plot[0], x, y); } IupPPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LINEWIDTH", "3"); IupSetAttribute(plot[0], "DS_LEGEND", "Line"); theFac = (float)2.0/100; IupPPlotBegin(plot[0], 0); for (theI=-100; theI<=100; theI++) { x = (float)theI; y = -theFac*theI; IupPPlotAdd(plot[0], x, y); } IupPPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LEGEND", "Curve 1"); IupPPlotBegin(plot[0], 0); for (theI=-100; theI<=100; theI++) { x = (float)(0.01*theI*theI-30); y = (float)0.01*theI; IupPPlotAdd(plot[0], x, y); } IupPPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LEGEND", "Curve 2"); /* PLOT 1 - MakeExamplePlot2 */ IupSetAttribute(plot[1], "TITLE", "No Autoscale+No CrossOrigin"); IupSetAttribute(plot[1], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[1], "MARGINTOP", "40"); IupSetAttribute(plot[1], "MARGINLEFT", "65"); IupSetAttribute(plot[1], "MARGINBOTTOM", "60"); IupSetAttribute(plot[1], "BGCOLOR", "0 192 192"); IupSetAttribute(plot[1], "AXS_XLABEL", "Tg (X)"); IupSetAttribute(plot[1], "AXS_YLABEL", "Tg (Y)"); IupSetAttribute(plot[1], "AXS_XAUTOMIN", "NO"); IupSetAttribute(plot[1], "AXS_XAUTOMAX", "NO"); IupSetAttribute(plot[1], "AXS_YAUTOMIN", "NO"); IupSetAttribute(plot[1], "AXS_YAUTOMAX", "NO"); IupSetAttribute(plot[1], "AXS_XMIN", "10"); IupSetAttribute(plot[1], "AXS_XMAX", "60"); IupSetAttribute(plot[1], "AXS_YMIN", "-0.5"); IupSetAttribute(plot[1], "AXS_YMAX", "0.5"); IupSetAttribute(plot[1], "AXS_XCROSSORIGIN", "NO"); IupSetAttribute(plot[1], "AXS_YCROSSORIGIN", "NO"); IupSetAttribute(plot[1], "AXS_XFONTSTYLE", "BOLD"); IupSetAttribute(plot[1], "AXS_YFONTSTYLE", "BOLD"); IupSetAttribute(plot[1], "AXS_XREVERSE", "YES"); IupSetAttribute(plot[1], "GRIDCOLOR", "128 255 128"); IupSetAttribute(plot[1], "GRIDLINESTYLE", "DOTTED"); IupSetAttribute(plot[1], "GRID", "YES"); IupSetAttribute(plot[1], "LEGENDSHOW", "YES"); theFac = (float)1.0/(100*100*100); IupPPlotBegin(plot[1], 0); for (theI=0; theI<=100; theI++) { x = (float)(theI); y = theFac*theI*theI*theI; IupPPlotAdd(plot[1], x, y); } IupPPlotEnd(plot[1]); theFac = (float)2.0/100; IupPPlotBegin(plot[1], 0); for (theI=0; theI<=100; theI++) { x = (float)(theI); y = -theFac*theI; IupPPlotAdd(plot[1], x, y); } IupPPlotEnd(plot[1]); /* PLOT 2 - MakeExamplePlot4 */ IupSetAttribute(plot[2], "TITLE", "Log Scale"); IupSetAttribute(plot[2], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[2], "MARGINTOP", "40"); IupSetAttribute(plot[2], "MARGINLEFT", "70"); IupSetAttribute(plot[2], "MARGINBOTTOM", "60"); IupSetAttribute(plot[2], "GRID", "YES"); IupSetAttribute(plot[2], "AXS_XSCALE", "LOG10"); IupSetAttribute(plot[2], "AXS_YSCALE", "LOG2"); IupSetAttribute(plot[2], "AXS_XLABEL", "Tg (X)"); IupSetAttribute(plot[2], "AXS_YLABEL", "Tg (Y)"); IupSetAttribute(plot[2], "AXS_XFONTSTYLE", "BOLD"); IupSetAttribute(plot[2], "AXS_YFONTSTYLE", "BOLD"); theFac = (float)100.0/(100*100*100); IupPPlotBegin(plot[2], 0); for (theI=0; theI<=100; theI++) { x = (float)(0.0001+theI*0.001); y = (float)(0.01+theFac*theI*theI*theI); IupPPlotAdd(plot[2], x, y); } IupPPlotEnd(plot[2]); IupSetAttribute(plot[2], "DS_COLOR", "100 100 200"); /* PLOT 3 - MakeExamplePlot5 */ IupSetAttribute(plot[3], "TITLE", "Bar Mode"); IupSetAttribute(plot[3], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[3], "MARGINTOP", "40"); IupSetAttribute(plot[3], "MARGINLEFT", "30"); IupSetAttribute(plot[3], "MARGINBOTTOM", "30"); { const char * kLables[12] = {"jan","feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; const float kData[12] = {1,2,3,4,5,6,7,8,9,0,1,2}; IupPPlotBegin(plot[3], 1); for (theI=0; theI<12; theI++) IupPPlotAddStr(plot[3], kLables[theI], kData[theI]); } IupPPlotEnd(plot[3]); IupSetAttribute(plot[3], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[3], "DS_MODE", "BAR"); /* PLOT 4 - MakeExamplePlot6 */ IupSetAttribute(plot[4], "TITLE", "Marks Mode"); IupSetAttribute(plot[4], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[4], "MARGINTOP", "40"); IupSetAttribute(plot[4], "MARGINLEFT", "45"); IupSetAttribute(plot[4], "MARGINBOTTOM", "40"); IupSetAttribute(plot[4], "AXS_XAUTOMIN", "NO"); IupSetAttribute(plot[4], "AXS_XAUTOMAX", "NO"); IupSetAttribute(plot[4], "AXS_YAUTOMIN", "NO"); IupSetAttribute(plot[4], "AXS_YAUTOMAX", "NO"); IupSetAttribute(plot[4], "AXS_XMIN", "0"); IupSetAttribute(plot[4], "AXS_XMAX", "0.011"); IupSetAttribute(plot[4], "AXS_YMIN", "0"); IupSetAttribute(plot[4], "AXS_YMAX", "0.22"); IupSetAttribute(plot[4], "AXS_XCROSSORIGIN", "NO"); IupSetAttribute(plot[4], "AXS_YCROSSORIGIN", "NO"); IupSetAttribute(plot[4], "AXS_XTICKFORMAT", "%1.3f"); IupSetAttribute(plot[4], "LEGENDSHOW", "YES"); IupSetAttribute(plot[4], "LEGENDPOS", "BOTTOMRIGHT"); theFac = (float)100.0/(100*100*100); IupPPlotBegin(plot[4], 0); for (theI=0; theI<=10; theI++) { x = (float)(0.0001+theI*0.001); y = (float)(0.01+theFac*theI*theI); IupPPlotAdd(plot[4], x, y); } IupPPlotEnd(plot[4]); IupSetAttribute(plot[4], "DS_MODE", "MARKLINE"); IupSetAttribute(plot[4], "DS_SHOWVALUES", "YES"); IupPPlotBegin(plot[4], 0); for (theI=0; theI<=10; theI++) { x = (float)(0.0001+theI*0.001); y = (float)(0.2-theFac*theI*theI); IupPPlotAdd(plot[4], x, y); } IupPPlotEnd(plot[4]); IupSetAttribute(plot[4], "DS_MODE", "MARK"); IupSetAttribute(plot[4], "DS_MARKSTYLE", "HOLLOW_CIRCLE"); /* PLOT 5 - MakeExamplePlot8 */ IupSetAttribute(plot[5], "TITLE", "Data Selection and Editing"); IupSetAttribute(plot[5], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[5], "MARGINTOP", "40"); theFac = (float)100.0/(100*100*100); IupPPlotBegin(plot[5], 0); for (theI=-10; theI<=10; theI++) { x = (float)(0.001*theI); y = (float)(0.01+theFac*theI*theI*theI); IupPPlotAdd(plot[5], x, y); } IupPPlotEnd(plot[5]); IupSetAttribute(plot[5], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[5], "DS_EDIT", "YES"); IupSetCallback(plot[5], "DELETE_CB", (Icallback)delete_cb); IupSetCallback(plot[5], "SELECT_CB", (Icallback)select_cb); IupSetCallback(plot[5], "POSTDRAW_CB", (Icallback)postdraw_cb); IupSetCallback(plot[5], "PREDRAW_CB", (Icallback)predraw_cb); IupSetCallback(plot[5], "EDIT_CB", (Icallback)edit_cb); } static int tabs_get_index(void) { Ihandle *curr_tab = IupGetHandle(IupGetAttribute(tabs, "VALUE")); char *ss = IupGetAttribute(curr_tab, "TABTITLE"); ss += 5; /* Skip "Plot " */ return atoi(ss); } /* Some processing required by current tab change: the controls at left will be updated according to current plot props */ static int tabs_tabchange_cb(Ihandle* self, Ihandle* new_tab) { int ii=0; char *ss = IupGetAttribute(new_tab, "TABTITLE"); ss += 5; /* Skip "Plot " */ ii = atoi(ss); /* autoscaling X axis */ if (IupGetInt(plot[ii], "AXS_XAUTOMIN") && IupGetInt(plot[ii], "AXS_XAUTOMAX")) { IupSetAttribute(tgg2, "VALUE", "ON"); IupSetAttribute(dial2, "ACTIVE", "NO"); } else { IupSetAttribute(tgg2, "VALUE", "OFF"); IupSetAttribute(dial2, "ACTIVE", "YES"); } /* autoscaling Y axis */ if (IupGetInt(plot[ii], "AXS_YAUTOMIN") && IupGetInt(plot[ii], "AXS_YAUTOMAX")) { IupSetAttribute(tgg1, "VALUE", "ON"); IupSetAttribute(dial1, "ACTIVE", "NO"); } else { IupSetAttribute(tgg1, "VALUE", "OFF"); IupSetAttribute(dial1, "ACTIVE", "YES"); } /* grid */ if (IupGetInt(plot[ii], "GRID")) { IupSetAttribute(tgg3, "VALUE", "ON"); IupSetAttribute(tgg4, "VALUE", "ON"); } else { /* X axis */ if (*IupGetAttribute(plot[ii], "GRID") == 'V') IupSetAttribute(tgg3, "VALUE", "ON"); else IupSetAttribute(tgg3, "VALUE", "OFF"); /* Y axis */ if (*IupGetAttribute(plot[ii], "GRID") == 'H') IupSetAttribute(tgg4, "VALUE", "ON"); else IupSetAttribute(tgg4, "VALUE", "OFF"); } /* legend */ if (IupGetInt(plot[ii], "LEGENDSHOW")) IupSetAttribute(tgg5, "VALUE", "ON"); else IupSetAttribute(tgg5, "VALUE", "OFF"); return IUP_DEFAULT; } /* show/hide V grid */ static int tgg3_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) { if (IupGetInt(tgg4, "VALUE")) IupSetAttribute(plot[ii], "GRID", "YES"); else IupSetAttribute(plot[ii], "GRID", "VERTICAL"); } else { if (!IupGetInt(tgg4, "VALUE")) IupSetAttribute(plot[ii], "GRID", "NO"); else IupSetAttribute(plot[ii], "GRID", "HORIZONTAL"); } IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* show/hide H grid */ static int tgg4_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) { if (IupGetInt(tgg3, "VALUE")) IupSetAttribute(plot[ii], "GRID", "YES"); else IupSetAttribute(plot[ii], "GRID", "HORIZONTAL"); } else { if (!IupGetInt(tgg3, "VALUE")) IupSetAttribute(plot[ii], "GRID", "NO"); else IupSetAttribute(plot[ii], "GRID", "VERTICAL"); } IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* show/hide legend */ static int tgg5_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) IupSetAttribute(plot[ii], "LEGENDSHOW", "YES"); else IupSetAttribute(plot[ii], "LEGENDSHOW", "NO"); IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* autoscale Y */ static int tgg1_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) { IupSetAttribute(dial1, "ACTIVE", "NO"); IupSetAttribute(plot[ii], "AXS_YAUTOMIN", "YES"); IupSetAttribute(plot[ii], "AXS_YAUTOMAX", "YES"); } else { IupSetAttribute(dial1, "ACTIVE", "YES"); IupSetAttribute(plot[ii], "AXS_YAUTOMIN", "NO"); IupSetAttribute(plot[ii], "AXS_YAUTOMAX", "NO"); } IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* autoscale X */ static int tgg2_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) { IupSetAttribute(dial2, "ACTIVE", "NO"); IupSetAttribute(plot[ii], "AXS_XAUTOMIN", "YES"); IupSetAttribute(plot[ii], "AXS_XAUTOMAX", "YES"); } else { IupSetAttribute(dial2, "ACTIVE", "YES"); IupSetAttribute(plot[ii], "AXS_XAUTOMIN", "NO"); IupSetAttribute(plot[ii], "AXS_XAUTOMAX", "NO"); } IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* Y zoom */ static int dial1_btndown_cb(Ihandle *self, double angle) { int ii = tabs_get_index(); IupStoreAttribute(plot[ii], "OLD_YMIN", IupGetAttribute(plot[ii], "AXS_YMIN")); IupStoreAttribute(plot[ii], "OLD_YMAX", IupGetAttribute(plot[ii], "AXS_YMAX")); return IUP_DEFAULT; } static int dial1_btnup_cb(Ihandle *self, double angle) { int ii = tabs_get_index(); double x1, x2, xm; char *ss; x1 = IupGetFloat(plot[ii], "OLD_YMIN"); x2 = IupGetFloat(plot[ii], "OLD_YMAX"); ss = IupGetAttribute(plot[ii], "AXS_YMODE"); if ( ss && ss[3]=='2' ) { /* LOG2: one circle will zoom 2 times */ xm = 4.0 * fabs(angle) / 3.141592; if (angle>0.0) { x2 /= xm; x1 *= xm; } else { x2 *= xm; x1 /= xm; } } if ( ss && ss[3]=='1' ) { /* LOG10: one circle will zoom 10 times */ xm = 10.0 * fabs(angle) / 3.141592; if (angle>0.0) { x2 /= xm; x1 *= xm; } else { x2 *= xm; x1 /= xm; } } else { /* LIN: one circle will zoom 2 times */ xm = (x1 + x2) / 2.0; x1 = xm - (xm - x1)*(1.0-angle*1.0/3.141592); x2 = xm + (x2 - xm)*(1.0-angle*1.0/3.141592); } if (x1