/* * IupPlot 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_PLOT */ #include #include #include #include #include "iup.h" #include "iupcontrols.h" #include "iup_plot.h" //#include "iupim.h" #include #include //#include #define MAXPLOT 6 /* room for examples */ static Ihandle *plot[MAXPLOT] = {NULL}; /* Plot 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, 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, cdCanvas* cnv) { double ix, iy; IupPlotTransform(ih, 0.003f, 0.02f, &ix, &iy); cdCanvasFont(cnv, NULL, CD_BOLD, 10); cdCanvasTextAlignment(cnv, CD_SOUTH); cdfCanvasText(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; double x, y, theFac; /************************************************************************/ /* PLOT 0 - MakeExamplePlot1 */ IupSetAttribute(plot[0], "TITLE", "AutoScale"); IupSetAttribute(plot[0], "FONT", "Helvetica, 10"); // 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_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[0], "AXS_YCROSSORIGIN", "Yes"); // IupSetAttribute(plot[0], "GRAPHICSMODE", "OPENGL"); // IupSetAttribute(plot[0], "GRAPHICSMODE", "IMAGERGB"); // IupSetAttribute(plot[0], "ACTIVE", "No"); #if 0 { Ihandle* image = IupLoadImage("../test/corsega.tif"); if (image) { IupSetAttributeHandle(plot[0], "BACKIMAGE", image); IupSetAttribute(plot[0], "BACKIMAGE_XMIN", "-100"); IupSetAttribute(plot[0], "BACKIMAGE_XMAX", "150"); IupSetAttribute(plot[0], "BACKIMAGE_YMIN", "-2"); IupSetAttribute(plot[0], "BACKIMAGE_YMAX", "2"); } } #endif theFac = 1.0/(100*100*100); IupPlotBegin(plot[0], 0); for (theI=-100; theI<=100; theI++) { x = (theI+50); y = theFac*theI*theI*theI; IupPlotAdd(plot[0], x, y); } IupPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LINEWIDTH", "3"); IupSetAttribute(plot[0], "DS_LEGEND", "Line"); // IupSetAttribute(plot[0], "DS_MODE", "AREA"); theFac = 2.0/100; IupPlotBegin(plot[0], 0); for (theI=-100; theI<0; theI++) { x = theI; y = -theFac*theI; IupPlotAdd(plot[0], x, y); } { int index = IupPlotEnd(plot[0]); /* add an empty plot */ double px[210], py[210]; int count = 0; for (theI=0; theI<=100; theI++) { x = theI; y = -theFac*theI; px[theI] = x; py[theI] = y; count++; } //IupPlotAddSamples(plot[0], index, px, py, count); IupPlotInsertSamples(plot[0], index, 100, px, py, count); } IupSetAttribute(plot[0], "DS_LEGEND", "Curve 1"); IupPlotBegin(plot[0], 0); for (theI=-100; theI<=100; theI++) { x = (0.01*theI*theI-30); y = 0.01*theI; IupPlotAdd(plot[0], x, y); } IupPlotEnd(plot[0]); IupSetAttribute(plot[0], "DS_LEGEND", "Curve 2"); /************************************************************************/ /* PLOT 1 */ IupSetAttribute(plot[1], "TITLE", "No Autoscale+No CrossOrigin"); IupSetAttribute(plot[1], "FONT", "Helvetica, 10"); // 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_XFONTSTYLE", "ITALIC"); 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"); IupSetAttribute(plot[1], "AXS_XLABELCENTERED", "Yes"); IupSetAttribute(plot[1], "AXS_YLABELCENTERED", "Yes"); IupSetAttribute(plot[1], "GRAPHICSMODE", "IMAGERGB"); theFac = 1.0/(100*100*100); IupPlotBegin(plot[1], 0); for (theI=0; theI<=100; theI++) { x = (theI); y = theFac*theI*theI*theI; IupPlotAdd(plot[1], x, y); } IupPlotEnd(plot[1]); theFac = 2.0/100; IupPlotBegin(plot[1], 0); for (theI=0; theI<=100; theI++) { x = (theI); y = -theFac*theI; IupPlotAdd(plot[1], x, y); } IupPlotEnd(plot[1]); /************************************************************************/ /* PLOT 2 */ 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 = 100.0/(100*100*100); IupPlotBegin(plot[2], 0); for (theI=0; theI<=100; theI++) { x = (0.0001+theI*0.001); y = (0.01+theFac*theI*theI*theI); IupPlotAdd(plot[2], x, y); } IupPlotEnd(plot[2]); IupSetAttribute(plot[2], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[2], "DS_LINESTYLE", "DOTTED"); /************************************************************************/ /* PLOT 3 */ 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 double kData[12] = {10,20,30,40,50,60,70,80,90,0,10,20}; IupPlotBegin(plot[3], 1); for (theI=0; theI<12; theI++) IupPlotAddStr(plot[3], kLables[theI], kData[theI]); } IupPlotEnd(plot[3]); IupSetAttribute(plot[3], "DS_COLOR", "100 100 200"); IupSetAttribute(plot[3], "DS_MODE", "BAR"); /************************************************************************/ /* PLOT 4 */ 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_XTICKFORMAT", "%1.3f"); IupSetAttribute(plot[4], "LEGENDSHOW", "YES"); IupSetAttribute(plot[4], "LEGENDPOS", "BOTTOMRIGHT"); theFac = 100.0/(100*100*100); IupPlotBegin(plot[4], 0); for (theI=0; theI<=10; theI++) { x = (0.0001+theI*0.001); y = (0.01+theFac*theI*theI); IupPlotAdd(plot[4], x, y); } IupPlotEnd(plot[4]); IupSetAttribute(plot[4], "DS_MODE", "MARKLINE"); IupPlotBegin(plot[4], 0); for (theI=0; theI<=10; theI++) { x = (0.0001+theI*0.001); y = (0.2-theFac*theI*theI); IupPlotAdd(plot[4], x, y); } IupPlotEnd(plot[4]); IupSetAttribute(plot[4], "DS_MODE", "MARK"); IupSetAttribute(plot[4], "DS_MARKSTYLE", "HOLLOW_CIRCLE"); /************************************************************************/ /* PLOT 5 */ IupSetAttribute(plot[5], "TITLE", "Data Selection and Editing"); //IupSetAttribute(plot[5], "TITLEFONTSIZE", "16"); //IupSetAttribute(plot[5], "MARGINTOP", "40"); #if 0 IupPlotLoadData(plot[5], "../test/plot.dat", 0); #else theFac = 100.0/(100*100*100); IupPlotBegin(plot[5], 0); for (theI=-10; theI<=10; theI++) { x = (0.001*theI); y = (0.01+theFac*theI*theI*theI); IupPlotAdd(plot[5], x, y); } IupPlotEnd(plot[5]); IupSetAttribute(plot[5], "AXS_XCROSSORIGIN", "Yes"); IupSetAttribute(plot[5], "AXS_YCROSSORIGIN", "Yes"); #endif IupSetAttribute(plot[5], "DS_COLOR", "100 100 200"); 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 *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