/* * IupMglPlot Test * Description : Create all built-in plots. * It is organized as two side-by-side panels: * - left panel for current plot control * - right panel containing tabbed plots * Remark : depend on libs IUP, CD, IUP_MGLPLOT */ #include #include #include #include //#define USE_IM 1 #ifdef USE_IM #include "im.h" #include "im_image.h" #include "im_convert.h" #include "im_process.h" #endif #include "iup.h" #ifdef USE_IM #include "iupim.h" #endif #include "iupcontrols.h" #include "iup_mglplot.h" #ifdef MGLPLOT_TEST #define MAXPLOT 6 /* room for examples */ static Ihandle *plot[MAXPLOT] = {NULL}; /* MglPlot controls */ static Ihandle *dial1, *dial2, /* dials for zooming */ *tgg1, *tgg2, /* auto scale on|off toggles */ *tgg3, *tgg4, /* grid show|hide toggles */ *tgg5, /* legend show|hide toggle */ *tgg6, /* box show|hide toggle */ *tabs; /* tabbed control */ static int delete_cb(Ihandle* ih, int index, int sample_index, double x, double 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, double x, double y, int select) { printf("SELECT_CB(%d, %d, %g, %g, %d)\n", index, sample_index, x, y, select); return IUP_DEFAULT; } static int postdraw_cb(Ihandle* ih) { IupMglPlotDrawText(ih, "My Inline Legend", 0.003f, 0.02f, 0); printf("POSTDRAW_CB()\n"); return IUP_DEFAULT; } static int predraw_cb(Ihandle* ih) { printf("PREDRAW_CB()\n"); return IUP_DEFAULT; } static void InitPlots(void) { int theI, ds_index, count; double x, y, theFac; double px[210], py[210]; /* PLOT 0 - MakeExamplePlot1 */ IupSetAttribute(plot[0], "TITLE", "AutoScale"); // IupSetAttribute(plot[0], "TITLEFONTSIZE", "16"); IupSetAttribute(plot[0], "LEGEND", "YES"); // IupSetAttribute(plot[0], "ALPHA", "NO"); // IupSetAttribute(plot[0], "ANTIALIAS", "NO"); // IupSetAttribute(plot[0], "FONT", "Helvetica, 14"); // IupSetAttribute(plot[0], "FONT", "Courier, 11"); // IupSetAttribute(plot[0], "FONT", "Times, 8"); // IupSetAttribute(plot[0], "FONT", "courbd, 8"); // IupSetAttribute(plot[0], "FONT", "texgyrecursor-bold, 8"); // IupSetAttribute(plot[0], "FONT", "cursor, Bold 8"); IupSetAttribute(plot[0], "MARGINTOP", "No"); IupSetAttribute(plot[0], "MARGINLEFT", "No"); IupSetAttribute(plot[0], "MARGINRIGHT", "No"); IupSetAttribute(plot[0], "MARGINBOTTOM", "No"); IupSetAttribute(plot[0], "AXS_XLABEL", "gnu (Foo)"); IupSetAttribute(plot[0], "AXS_YLABEL", "Space (m^3)"); // IupSetAttribute(plot[0], "AXS_XTICKFONTSIZE", "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], "AXS_YLABELROTATION", "NO"); IupSetAttribute(plot[0], "AXS_YTICKVALUESROTATION", "NO"); // IupSetAttribute(plot[0], "AXS_XTICKVALUESROTATION", "NO"); IupSetAttribute(plot[0], "AXS_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[0], "AXS_YCROSSORIGIN", "Yes"); theFac = 1.0/(100*100*100); IupMglPlotBegin(plot[0], 2); for (theI=-100; theI<=100; theI++) { x = (theI+50); y = theFac*theI*theI*theI; IupMglPlotAdd2D(plot[0], x, y); } IupMglPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LINEWIDTH", "3"); IupSetAttribute(plot[0], "DS_LEGEND", "Line"); //IupSetAttribute(plot[0], "DS_COLOR", "0 128 255"); theFac = 2.0/100; ds_index = IupMglPlotNewDataSet(plot[0], 2); count = 0; for (theI=-100; theI<=100; theI++) { x = theI; y = -theFac*theI; px[theI+100] = x; py[theI+100] = y; count++; } IupMglPlotSet2D(plot[0], ds_index, px, py, count); IupSetAttribute(plot[0], "DS_LEGEND", "Curve 1"); IupMglPlotBegin(plot[0], 2); for (theI=-100; theI<=100; theI++) { x = (0.01*theI*theI-30); y = 0.01*theI; IupMglPlotAdd2D(plot[0], x, y); } IupMglPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LEGEND", "Curve 2"); /* PLOT 1 - MakeExamplePlot2 */ IupSetAttribute(plot[1], "TITLE", "No Autoscale+No CrossOrigin"); 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_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_XFONTSTYLE", "ITALIC"); IupSetAttribute(plot[1], "AXS_YFONTSTYLE", "BOLD"); IupSetAttribute(plot[1], "AXS_XREVERSE", "YES"); IupSetAttribute(plot[1], "AXS_XORIGIN", "60"); IupSetAttribute(plot[1], "GRIDCOLOR", "128 255 128"); IupSetAttribute(plot[1], "GRIDLINESTYLE", "DOTTED"); IupSetAttribute(plot[1], "GRID", "YES"); IupSetAttribute(plot[1], "BOX", "YES"); IupSetAttribute(plot[1], "LEGEND", "YES"); //IupSetAttribute(plot[1], "AXS_XCROSSORIGIN", "Yes"); //IupSetAttribute(plot[1], "AXS_YCROSSORIGIN", "Yes"); //IupSetAttribute(plot[1], "AXS_YTICKVALUESROTATION", "NO"); theFac = 1.0/(100*100*100); IupMglPlotBegin(plot[1], 2); for (theI=0; theI<=100; theI++) { x = (double)(theI); y = theFac*theI*theI*theI; IupMglPlotAdd2D(plot[1], x, y); } IupMglPlotEnd(plot[1]); theFac = 2.0/100; IupMglPlotBegin(plot[1], 2); for (theI=0; theI<=100; theI++) { x = (double)(theI); y = -theFac*theI; IupMglPlotAdd2D(plot[1], x, y); } IupMglPlotEnd(plot[1]); /* PLOT 2 - MakeExamplePlot4 */ IupSetAttribute(plot[2], "TITLE", "Log Scale"); IupSetAttribute(plot[2], "GRID", "YES"); IupSetAttribute(plot[2], "BOX", "YES"); IupSetAttribute(plot[2], "BOXTICKS", "NO"); 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"); // IupSetAttribute(plot[2], "AXS_XLABELCENTERED", "NO"); // IupSetAttribute(plot[2], "AXS_YLABELCENTERED", "NO"); // IupSetAttribute(plot[2], "AXS_YLABELROTATION", "NO"); IupSetAttribute(plot[2], "AXS_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[2], "AXS_YCROSSORIGIN", "Yes"); IupSetAttribute(plot[2], "MARGINTOP", "No"); IupSetAttribute(plot[2], "MARGINRIGHT", "No"); theFac = 100.0/(100*100*100); IupMglPlotBegin(plot[2], 2); for (theI=0; theI<=100; theI++) { x = (0.0001+theI*0.001); y = (0.01+theFac*theI*theI*theI); IupMglPlotAdd2D(plot[2], x, y); } IupMglPlotEnd(plot[2]); IupSetAttribute(plot[2], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[2], "DS_LINESTYLE", "DOTTED"); /* PLOT 3 - MakeExamplePlot5 */ IupSetAttribute(plot[3], "TITLE", "Bar Mode"); IupSetAttribute(plot[3], "AXS_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[3], "AXS_YCROSSORIGIN", "Yes"); IupSetAttribute(plot[3], "MARGINTOP", "No"); IupSetAttribute(plot[3], "MARGINLEFT", "No"); IupSetAttribute(plot[3], "MARGINRIGHT", "No"); IupSetAttribute(plot[3], "MARGINBOTTOM", "No"); { const char * kLables[12] = {"jan","feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; const double kData[12] = {10,20,30,40,50,60,70,80,90,0,10,20}; IupMglPlotBegin(plot[3], 1); for (theI=0; theI<12; theI++) IupMglPlotAdd1D(plot[3], kLables[theI], kData[theI]); } IupMglPlotEnd(plot[3]); IupSetAttribute(plot[3], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[3], "DS_MODE", "BAR"); // IupSetAttribute(plot[3], "AXS_XTICKAUTO", "NO"); // Not supported when names are used // IupSetAttribute(plot[3], "AXS_XTICKMAJORSPAN", "-5"); // idem /* PLOT 4 - MakeExamplePlot6 */ IupSetAttribute(plot[4], "TITLE", "Marks Mode"); 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_XTICKFORMAT", "%1.3f"); IupSetAttribute(plot[4], "LEGEND", "YES"); IupSetAttribute(plot[4], "LEGENDPOS", "BOTTOMRIGHT"); // IupSetAttribute(plot[4], "AXS_YTICKVALUESROTATION", "NO"); IupSetAttribute(plot[4], "MARGINTOP", "No"); IupSetAttribute(plot[4], "MARGINLEFT", "No"); IupSetAttribute(plot[4], "MARGINRIGHT", "No"); IupSetAttribute(plot[4], "MARGINBOTTOM", "No"); theFac = 100.0/(100*100*100); IupMglPlotBegin(plot[4], 2); for (theI=0; theI<=10; theI++) { x = (0.0001+theI*0.001); y = (0.01+theFac*theI*theI); IupMglPlotAdd2D(plot[4], x, y); } IupMglPlotEnd(plot[4]); IupSetAttribute(plot[4], "DS_MODE", "MARKLINE"); IupSetAttribute(plot[4], "DS_SHOWVALUES", "YES"); IupMglPlotBegin(plot[4], 2); for (theI=0; theI<=10; theI++) { x = (0.0001+theI*0.001); y = (0.2-theFac*theI*theI); IupMglPlotAdd2D(plot[4], x, y); } IupMglPlotEnd(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], "AXS_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[5], "AXS_YCROSSORIGIN", "Yes"); IupSetAttribute(plot[5], "MARGINTOP", "No"); IupSetAttribute(plot[5], "MARGINLEFT", "No"); IupSetAttribute(plot[5], "MARGINRIGHT", "No"); IupSetAttribute(plot[5], "MARGINBOTTOM", "No"); theFac = 100.0/(100*100*100); IupMglPlotBegin(plot[5], 2); for (theI=-10; theI<=10; theI++) { x = (0.001*theI); y = (0.01+theFac*theI*theI*theI); IupMglPlotAdd2D(plot[5], x, y); } IupMglPlotEnd(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); } 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 *value = IupGetAttribute(new_tab, "TABTITLE"); ii = atoi(value+5); /* Skip "Plot " */ /* auto scaling 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"); } /* auto scaling 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 */ value = IupGetAttribute(plot[ii], "GRID"); if (value && strstr(value, "X")) IupSetAttribute(tgg3, "VALUE", "ON"); else IupSetAttribute(tgg3, "VALUE", "OFF"); if (value && strstr(value, "Y")) IupSetAttribute(tgg4, "VALUE", "ON"); else IupSetAttribute(tgg4, "VALUE", "OFF"); /* legend */ if (IupGetInt(plot[ii], "LEGEND")) IupSetAttribute(tgg5, "VALUE", "ON"); else IupSetAttribute(tgg5, "VALUE", "OFF"); /* box */ if (IupGetInt(plot[ii], "BOX")) IupSetAttribute(tgg6, "VALUE", "ON"); else IupSetAttribute(tgg6, "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 box */ static int tgg6_cb(Ihandle *self, int v) { int ii = tabs_get_index(); if (v) IupSetAttribute(plot[ii], "BOX", "YES"); else IupSetAttribute(plot[ii], "BOX", "NO"); IupSetAttribute(plot[ii], "BOXTICKS", "NO"); 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], "LEGEND", "YES"); else IupSetAttribute(plot[ii], "LEGEND", "NO"); IupSetAttribute(plot[ii], "REDRAW", NULL); return IUP_DEFAULT; } /* auto scale 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; } /* auto scale 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 (x1data[0], w, h, 3, 3, IM_BYTE, 1); imProcessFlip(image, image); imFileImageSave("../mglplot.png", "PNG", image); free(gldata); imImageDestroy(image); (void)self; return IUP_DEFAULT; } #else static int bt1_cb(Ihandle *self) { int ii = tabs_get_index(); // IupSetAttribute(plot[ii], "CLEAR", "Yes"); // IupSetAttribute(plot[ii], "REMOVE", "0"); // IupSetAttribute(plot[ii], "ANTIALIAS", !IupGetInt(plot[ii], "ANTIALIAS")? "Yes": "No"); IupSetAttribute(plot[ii], "OPENGL", !IupGetInt(plot[ii], "OPENGL")? "Yes": "No"); IupSetAttribute(plot[ii], "REDRAW", NULL); // IupMglPlotPaintTo(plot[ii], "EPS", 0, 0, 0, "../mglplot.eps"); // IupMglPlotPaintTo(plot[ii], "SVG", 0, 0, 0, "../mglplot.svg"); return IUP_DEFAULT; } #endif void MglPlotTest(void) { static Ihandle *dlg = NULL; if (!dlg) { Ihandle *vboxr[MAXPLOT+1]; /* tabs containing the plots */ Ihandle *vboxl, *hbox, *lbl1, *lbl2, *lbl3, *bt1, *boxinfo, *boxdial1, *boxdial2, *f1, *f2; int ii; IupControlsOpen(); IupMglPlotOpen(); /* init IupMGLPlot library */ IupSetGlobal("MGLFONTS", "../etc/mglfonts"); /* create plots */ for (ii=0; ii