/* * IupMglPlot component * * Description : A component, derived from MathGL and IupGLCanvas * Remark : Depend on libs IUP, IUPGL, OpenGL */ #include #include #include #include #include #include #include "iup.h" #include "iupcbs.h" #include "iupkey.h" #include "iupgl.h" #include "iup_mglplot.h" #include "iup_assert.h" #include "iup_class.h" #include "iup_register.h" #include "iup_object.h" #include "iup_attrib.h" #include "iup_str.h" #include "iup_drvfont.h" #include "iup_stdcontrols.h" #include "iup_array.h" #include "iup_childtree.h" #ifdef WIN32 #include #endif #include #pragma warning(push, 0) #include "mgl2/mgl.h" #pragma warning(pop) enum {IUP_MGLPLOT_BOTTOMLEFT, IUP_MGLPLOT_BOTTOMRIGHT, IUP_MGLPLOT_TOPLEFT, IUP_MGLPLOT_TOPRIGHT}; #define MAX_FONTSTYLE 32 // Same as MathGL typedef struct _IdataSet { char dsLineStyle; int dsLineWidth; bool dsShowMarks; char dsMarkStyle; double dsMarkSize; bool dsShowValues; char* dsMode; char* dsLegend; mglColor dsColor; Iarray* dsNames; /* optional names used in ticks when in 1D */ int dsDim; /* Dimension of the data: 1D, 2D or 3D */ mglData* dsX; /* Linear (dsDim=1,2,3), Planar (dsDim=1) or Volumetric (dsDim=1) */ mglData* dsY; /* Linear Only (dsDim=2,3) */ mglData* dsZ; /* Linear Only (dsDim=3) */ int dsCount; } IdataSet; typedef struct _Iaxis { mglColor axColor; double axOrigin; char* axScale; bool axShow, axShowArrow; int axLabelPos; char axLabelFontStyle[MAX_FONTSTYLE]; double axLabelFontSizeFactor; bool axLabelRotation; char axTickFontStyle[MAX_FONTSTYLE]; double axTickFontSizeFactor; bool axTickShowValues, axTickShow, axTickAutoSpace, axTickAutoSize; double axTickMinorSizeFactor, axTickMajorSize; int axTickMinorDivision; double axTickMajorSpan; bool axTickValuesRotation; bool axReverse; double axMax, axMin; bool axAutoScaleMax, axAutoScaleMin; } Iaxis; struct _IcontrolData { iupCanvas canvas; /* from IupCanvas (must reserve it) */ mglGraph* mgl; /* Control */ int w, h; double dpi; bool redraw; bool opengl; /* Obtained from FONT */ double FontSizeDef; char FontStyleDef[MAX_FONTSTYLE]; /* Global */ bool transparent; double alpha; mglColor bgColor, fgColor; /* Title */ mglColor titleColor; char titleFontStyle[MAX_FONTSTYLE]; double titleFontSizeFactor; /* Axes */ Iaxis axisX, axisY, axisZ; /* Interaction */ double last_x, last_y; // Last Mouse Position double x1, x2, y1, y2; // Zoom+Pan double rotX, rotZ, rotY; // Rotate (angle in degrees) /* Box */ bool Box, boxTicks; mglColor boxColor; /* Legend */ bool legendShow, legendBox; mglColor legendColor; int legendPosition; char legendFontStyle[MAX_FONTSTYLE]; double legendFontSizeFactor; /* Grid */ mglColor gridColor; char* gridShow; char gridLineStyle; /* Dataset */ int dataSetCurrent; int dataSetCount, dataSetMaxCount; IdataSet* dataSet; }; /****************************************************************************** Useful Functions ******************************************************************************/ // Quantize 0-1 values into 0-255. inline unsigned char iQuant(const double& value) { if (value >= 1.0) return 255; if (value <= 0.0) return 0; return (unsigned char)(value*256.0); } // Reconstruct 0-255 values into 0-1. inline float iRecon(const unsigned char& value) { if (value <= 0) return 0.0f; if (value >= 255) return 1.0f; return ((float)value + 0.5f) / 256.0f; } inline void iSwap(double& a, double& b) { double tmp = a; a = b; b = tmp; } static char* iMglPlotDefaultLegend(int ds) { char legend[50]; sprintf(legend, "plot %d", ds); return iupStrDup(legend); } static void iMglPlotSetDsColorDefault(mglColor &color, int index) { switch(index) { case 0: color.Set(1, 0, 0); break; case 1: color.Set(0, 1, 0); break; case 2: color.Set(0, 0, 1); break; case 3: color.Set(0, 1, 1); break; case 4: color.Set(1, 0, 1); break; case 5: color.Set(1, 1, 0); break; case 6: color.Set(0.5f, 0, 0); break; case 7: color.Set(0, 0.5f, 0); break; case 8: color.Set(0, 0, 0.5f); break; case 9: color.Set(0, 0.5f, 0.5f); break; case 10: color.Set(0.5f, 0, 0.5f); break; case 11: color.Set(0.5f, 0.5f, 0); break; default: color.Set(0, 0, 0); break; } } static void iMglPlotDataSetDefaults(Ihandle* ih, IdataSet* ds, int ds_index) { // Can NOT use memset here ds->dsLineStyle = '-'; // "CONTINUOUS" ds->dsLineWidth = 1; ds->dsMarkStyle = 'x'; // "X" ds->dsMarkSize = 1.0; ds->dsShowMarks = false; ds->dsShowValues = false; ds->dsMode = iupStrDup("LINE"); ds->dsLegend = iMglPlotDefaultLegend(ds_index); int c = 0, i; mglColor color; do { iMglPlotSetDsColorDefault(color, c); for (i = 0; i < ih->data->dataSetCount; i++) { if (ih->data->dataSet[i].dsColor == color) break; } if (i == ih->data->dataSetCount) break; c++; } while (c < 12); ds->dsColor = color; } static void iMglPlotResetInteraction(Ihandle *ih) { ih->data->x1 = 0.0; ih->data->y1 = 0.0; ih->data->x2 = 1.0; ih->data->y2 = 1.0; ih->data->last_x = 0.0; ih->data->last_y = 0.0; ih->data->rotX = 0.0; ih->data->rotZ = 0.0; ih->data->rotY = 0.0; } static void iMglPlotResetAxis(Iaxis& axis) { memset(&axis, 0, sizeof(Iaxis)); axis.axLabelFontSizeFactor = 0.8; axis.axTickFontSizeFactor = 0.8; axis.axColor.Set(NAN, NAN, NAN); axis.axAutoScaleMin = true; axis.axAutoScaleMax = true; axis.axMin = -1; axis.axMax = 1; axis.axShow = true; axis.axShowArrow = true; axis.axLabelRotation = true; axis.axOrigin = NAN; axis.axTickShow = true; axis.axTickShowValues = true; axis.axTickValuesRotation = true; axis.axTickAutoSpace = true; axis.axTickAutoSize = true; axis.axTickMinorSizeFactor = 1.0; axis.axTickMajorSize = 0.02; axis.axTickMinorDivision = 5; axis.axTickMajorSpan = -5; } static void iMglPlotReset(Ihandle* ih) { // Can NOT use memset here ih->data->legendPosition = IUP_MGLPLOT_TOPRIGHT; ih->data->legendBox = true; ih->data->legendShow = false; ih->data->Box = false; ih->data->boxTicks = true; ih->data->gridLineStyle = '-'; ih->data->gridShow = NULL; ih->data->alpha = 0.5; ih->data->transparent = false; ih->data->titleFontStyle[0] = 0; ih->data->legendFontStyle[0] = 0; ih->data->legendFontSizeFactor = 1.0; ih->data->titleFontSizeFactor = 1.0; ih->data->bgColor.Set(1, 1, 1); ih->data->fgColor.Set(0, 0, 0); ih->data->gridColor.Set(iRecon(200), iRecon(200), iRecon(200)); ih->data->titleColor.Set(NAN, NAN, NAN); ih->data->legendColor.Set(NAN, NAN, NAN); ih->data->boxColor.Set(NAN, NAN, NAN); iMglPlotResetAxis(ih->data->axisX); iMglPlotResetAxis(ih->data->axisY); iMglPlotResetAxis(ih->data->axisZ); ih->data->axisY.axTickValuesRotation = false; /* Interaction default values */ iMglPlotResetInteraction(ih); } static bool iMglPlotIsPlanarOrVolumetricData(IdataSet* ds) { return (ds->dsDim == 1 && (ds->dsX->ny>1 || ds->dsX->nz>1)); } static bool iMglPlotIsPlanarData(IdataSet* ds) { return (ds->dsDim == 1 && ds->dsX->ny>1 && ds->dsX->nz==1); } static bool iMglPlotIsVolumetricData(IdataSet* ds) { return (ds->dsDim == 1 && ds->dsX->nz>1); } static bool iMglPlotIsView3D(Ihandle* ih) { int i; for (i=0; i< ih->data->dataSetCount; i++) { IdataSet* ds = &ih->data->dataSet[i]; if ((ds->dsDim == 1 && (ds->dsX->ny>1 || ds->dsX->nz>1)) || // Planar or Volumetric ds->dsDim == 3) // 3D data { if (!iupStrEqualNoCase(ds->dsMode, "PLANAR_DENSITY") && !iupStrEqualNoCase(ds->dsMode, "PLANAR_GRADIENTLINES")) return true; } } return false; } static char* iMglPlotGetTexFontName(const char* typeface) { if (iupStrEqualNoCase(typeface, "sans") || iupStrEqualNoCase(typeface, "helvetica") || iupStrEqualNoCase(typeface, "arial")) return "heros"; if (iupStrEqualNoCase(typeface, "monospace") || iupStrEqualNoCase(typeface, "courier") || iupStrEqualNoCase(typeface, "courier new")) return "cursor"; if (iupStrEqualNoCase(typeface, "serif") || iupStrEqualNoCase(typeface, "times") || iupStrEqualNoCase(typeface, "times new roman")) return "termes"; return NULL; } static void iMglPlotConfigFontDef(Ihandle* ih, mglGraph *gr, const char* font) { int size = 0, i = 0; int is_bold = 0, is_italic = 0, is_underline = 0, is_strikeout = 0; char typeface[1024]; if (!iupGetFontInfo(font, typeface, &size, &is_bold, &is_italic, &is_underline, &is_strikeout)) return; ih->data->FontStyleDef[i++] = ':'; // color separator if (is_bold && is_italic) { ih->data->FontStyleDef[i++] = 'b'; ih->data->FontStyleDef[i++] = 'i'; } else if (is_bold) { ih->data->FontStyleDef[i++] = 'b'; } else if (is_italic) { ih->data->FontStyleDef[i++] = 'i'; } else { ih->data->FontStyleDef[i++] = 'r'; } if (is_underline) ih->data->FontStyleDef[i++] = 'u'; if (is_strikeout) ih->data->FontStyleDef[i++] = 'o'; ih->data->FontStyleDef[i] = 0; if (size < 0) size = -size; else size = (int)((size*ih->data->dpi)/72.0); //from points to pixels // Smaller than the MathGL default (4) ih->data->FontSizeDef = 3.5; gr->SetFontSize(ih->data->FontSizeDef); char *path = getenv("IUP_MGLFONTS"); if (!path) path = IupGetGlobal("MGLFONTS"); if (!iupStrEqualNoCase(typeface, iupAttribGetStr(ih, "_IUP_MGL_FONTNAME")) || !iupStrEqualNoCase(path, iupAttribGetStr(ih, "_IUP_MGL_FONTPATH"))) { const char* fontname = iMglPlotGetTexFontName(typeface); if (!fontname) fontname = typeface; gr->LoadFont(fontname, path); // Load MathGL VFM fonts iupAttribSetStr(ih, "_IUP_MGL_FONTNAME", typeface); iupAttribSetStr(ih, "_IUP_MGL_FONTPATH", path); } } static double iMglPlotGetAttribDoubleNAN(Ihandle* ih, const char* name) { double val = NAN; iupStrToDouble(iupAttribGet(ih, name), &val); return val; } static void iMglPlotAddStyleLine(char* style, char line_style, int line_width) { style += strlen(style); // Skip previous configuration *style++ = line_style; if (line_width < 1) line_width = 1; if (line_width > 9) line_width = 9; *style++ = (char)('0' + line_width); *style = 0; } static char iMglPlotFindColor(const mglColor& c1) { int i; /* Search in the pre-defined MathGL Color Ids */ for(i=0; mglColorIds[i].id; i++) { if (c1 == mglColorIds[i].col) return mglColorIds[i].id; } return 0; } static void iMglPlotAddStyleColor(Ihandle* ih, char* style, mglColor color) { style += strlen(style); // Skip previous configuration // Check for NAN values and replace by default if (mgl_isnan(color.r) || mgl_isnan(color.g) || mgl_isnan(color.b)) color = ih->data->fgColor; // Check for a more compact representation char id = iMglPlotFindColor(color); if (id) { *style++ = id; *style = 0; } else { if (color.a == 1) sprintf(style, "{x%02X%02X%02X}", (int)iQuant(color.r), (int)iQuant(color.g), (int)iQuant(color.b)); else sprintf(style, "{x%02X%02X%02X%02X}", (int)iQuant(color.r), (int)iQuant(color.g), (int)iQuant(color.b), (int)iQuant(color.a)); } } static int iMglPlotAddStyleFont(char* style, const char* value) { if (!value || value[0]==0) return 0; style += strlen(style); // Skip previous configuration char* old_style = style; if (iupStrCompareFind(value, "PLAIN", 0, 0) || iupStrCompareFind(value, "REGULAR", 0, 0)) { *style++ = 'r'; *style = 0; } else { if (iupStrCompareFind(value, "BOLD", 0, 0)) { *style++ = 'b'; *style = 0; } if (iupStrCompareFind(value, "ITALIC", 0, 0) || iupStrCompareFind(value, "OBLIQUE", 0, 0)) { *style++ = 'i'; *style = 0; } } if (iupStrCompareFind(value, "WIRED", 0, 0)) { *style++ = 'w'; *style = 0; } if (iupStrCompareFind(value, "UNDERLINE", 0, 0)) { *style++ = 'u'; *style = 0; } if (iupStrCompareFind(value, "STRIKEOUT", 0, 0) || iupStrCompareFind(value, "OVERLINE", 0, 0)) { *style++ = 'o'; *style = 0; } if (iupStrCompareFind(value, "LEFT", 0, 0)) { *style++ = 'L'; *style = 0; } else if (iupStrCompareFind(value, "CENTER", 0, 0)) { *style++ = 'C'; *style = 0; } else if (iupStrCompareFind(value, "RIGHT", 0, 0)) { *style++ = 'R'; *style = 0; } if (old_style != style) return 1; else return 0; } static void iMglPlotAddStyleMark(char* style, char markstyle) { style += strlen(style); // Skip previous configuration // Fix mark codes if (markstyle == 'O' || markstyle == 'S' || markstyle == 'D' || markstyle == '^' || markstyle == 'V' || markstyle == '<' || markstyle == '>') { *style++ = '#'; // Conflict with datagrid, can not use these marks *style++ = (char)tolower(markstyle); } else *style++ = markstyle; *style = 0; } static void iMglPlotConfigFont(Ihandle* ih, mglGraph *gr, const mglColor* color, const char* fontstyle, double fontsizefactor) { char font[64] = ""; if (color) iMglPlotAddStyleColor(ih, font, *color); strcat(font, ":"); if (fontstyle[0] != 0) strcat(font, fontstyle); else strcat(font, ih->data->FontStyleDef); gr->SetFontDef(font); gr->SetFontSize(fontsizefactor*ih->data->FontSizeDef); } static void iMglPlotConfigDataSetLineMark(IdataSet* ds, mglGraph *gr, char* style) { iMglPlotAddStyleLine(style, ds->dsLineStyle, ds->dsLineWidth); if (ds->dsShowMarks) { iMglPlotAddStyleMark(style, ds->dsMarkStyle); gr->SetMarkSize(ds->dsMarkSize); } } static void iMglPlotConfigAxisTicks(Ihandle* ih, mglGraph *gr, char dir, const Iaxis& axis, double min, double max) { if (!axis.axTickShow) { gr->SetTicks(dir, 0, 0); return; } //Set Scale only if ticks are enabled if (axis.axScale) // Logarithm Scale { gr->SetTicks(dir, 0, 0); // Disable normal ticks, logarithm ticks will be done } else { // step for axis ticks (if positive) or // it's number on the axis range (if negative). double step = -5; int numsub = 0; // Number of axis submarks if (axis.axTickAutoSpace) { // Copied from MathGL AdjustTicks internal function // TODO: improve autoticks computation mreal n, d = fabs(max-min); n = floor(log10(d)); d = floor(d*pow(10,-n)); step = pow(10,n); if (d<4) { step *= 0.5; numsub = 4; } else if(d<7) numsub = 4; else { step *= 2; numsub = 3; } } else { numsub = axis.axTickMinorDivision-1; step = axis.axTickMajorSpan; } gr->SetTicks(dir, step, numsub); } // Setting the template, switches off automatic ticks tuning char attrib[16] = "AXS_?TICKFORMAT"; attrib[4] = dir; iupStrUpper(attrib, attrib); char* format = iupAttribGetStr(ih, attrib); if (format && axis.axTickShowValues) { if (dir == 'x') gr->SetTickTempl('x', format); if (dir == 'y') gr->SetTickTempl('y', format); if (dir == 'z') gr->SetTickTempl('z', format); if (dir == 'c') gr->SetTickTempl('c', format); } } static void iMglPlotConfigScale(Iaxis& axis, double& min, double& max) { if (!axis.axAutoScaleMax) max = axis.axMax; if (!axis.axAutoScaleMin) min = axis.axMin; if (axis.axScale) // Logarithm Scale { if (min < 0) min = 0; if (max < 0) max = 0; } if (axis.axReverse) iSwap(min, max); if (axis.axAutoScaleMax) axis.axMax = max; // Update the attribute value if (axis.axAutoScaleMin) axis.axMin = min; // Update the attribute value } static void iMglPlotFindMinMaxValues(mglData& ds_data, bool add, double& min, double& max) { int i, count = ds_data.nx*ds_data.ny*ds_data.nz; double* data = ds_data.a; for (i = 1; i < count; i++, data++) { if (mgl_isnan(*data)) continue; if (!add) // first valid found { min = *data; max = *data; add = true; } else { min = min<*data ? min: *data; max = max>*data ? max: *data; } } } static void iMglPlotConfigAxesRange(Ihandle* ih, mglGraph *gr) { int i; mglPoint Min(ih->data->axisX.axMin, ih->data->axisY.axMin, ih->data->axisZ.axMin); mglPoint Max(ih->data->axisX.axMax, ih->data->axisY.axMax, ih->data->axisZ.axMax); if (ih->data->axisX.axAutoScaleMax || ih->data->axisX.axAutoScaleMin || ih->data->axisY.axAutoScaleMax || ih->data->axisY.axAutoScaleMin || ih->data->axisZ.axAutoScaleMax || ih->data->axisZ.axAutoScaleMin) { for(i = 0; i < ih->data->dataSetCount; i++) { IdataSet* ds = &ih->data->dataSet[i]; bool add = i==0? false: true; mglPoint oldMin = Min; mglPoint oldMax = Max; if (iupStrEqualNoCase(ds->dsMode, "RADAR")) add = false; if (ds->dsDim == 1) { if (ds->dsX->ny>1 || ds->dsX->nz>1) /* Planar or Volumetric data */ { if (ih->data->axisX.axAutoScaleMax || ih->data->axisX.axAutoScaleMin) { Min.x = -1.0; Max.x = +1.0; } if (ih->data->axisY.axAutoScaleMax || ih->data->axisY.axAutoScaleMin) { Min.y = -1.0; Max.y = +1.0; } if (ih->data->axisZ.axAutoScaleMax || ih->data->axisZ.axAutoScaleMin) { Min.z = -1.0; Max.z = +1.0; } } else /* 1D Linear data */ { /* the data will be plotted as Y, X will be 0,1,2,3,... */ if (ih->data->axisX.axAutoScaleMax || ih->data->axisX.axAutoScaleMin) { Min.x = 0; double ds_max = (mreal)(ds->dsCount-1); Max.x = i==0? ds_max: (ds_max>Max.x? ds_max: Max.x); } if (ih->data->axisY.axAutoScaleMax || ih->data->axisY.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsX, add, Min.y, Max.y); if (iupStrEqualNoCase(ds->dsMode, "BARHORIZONTAL")) { iSwap(Min.x, Min.y); iSwap(Max.x, Max.y); } else if (iupStrEqualNoCase(ds->dsMode, "RADAR")) { double r = iupAttribGetDouble(ih, "RADARSHIFT"); // Default -1 if(r<0) r = (Min.y<0)? -Min.y:0; double rmax = fabs(Max.y)>fabs(Min.y)?fabs(Max.y):fabs(Min.y); double min = -(r + rmax); double max = (r + rmax); if (i==0) { Min.y = Min.x = min; Max.y = Max.x = max; } else { if (min < oldMin.x) Min.y = Min.x = min; else Min.y = Min.x = oldMin.x; if (max > oldMax.x) Max.y = Max.x = max; else Max.y = Max.x = oldMax.x; } oldMin = Min; oldMax = Max; } else if (iupStrEqualNoCase(ds->dsMode, "CHART") && iupAttribGetBoolean(ih, "PIECHART")) { double rmax = fabs(Max.y)>fabs(Min.y)?fabs(Max.y):fabs(Min.y); Min.y = Min.x = -rmax; Max.y = Max.x = rmax; } } } else if (ds->dsDim == 2) /* 2D Linear data */ { if (ih->data->axisX.axAutoScaleMax || ih->data->axisX.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsX, add, Min.x, Max.x); if (ih->data->axisY.axAutoScaleMax || ih->data->axisY.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsY, add, Min.y, Max.y); } else if (ds->dsDim == 3) /* 2D Linear data */ { if (ih->data->axisX.axAutoScaleMax || ih->data->axisX.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsX, add, Min.x, Max.x); if (ih->data->axisY.axAutoScaleMax || ih->data->axisY.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsY, add, Min.y, Max.y); if (ih->data->axisZ.axAutoScaleMax || ih->data->axisZ.axAutoScaleMin) iMglPlotFindMinMaxValues(*ds->dsZ, add, Min.z, Max.z); } } } iMglPlotConfigScale(ih->data->axisX, Min.x, Max.x); iMglPlotConfigScale(ih->data->axisY, Min.y, Max.y); iMglPlotConfigScale(ih->data->axisZ, Min.z, Max.z); gr->SetRange('x', Min.x, Max.x); gr->SetRange('y', Min.y, Max.y); gr->SetRange('z', Min.z, Max.z); iMglPlotConfigAxisTicks(ih, gr, 'x', ih->data->axisX, Min.x, Max.x); iMglPlotConfigAxisTicks(ih, gr, 'y', ih->data->axisY, Min.y, Max.y); iMglPlotConfigAxisTicks(ih, gr, 'z', ih->data->axisZ, Min.z, Max.z); // Color Range double Cmin, Cmax; char* coloraxisticks = iupAttribGetStr(ih, "COLORBARAXISTICKS"); char* value = iupAttribGetStr(ih, "COLORBARRANGE"); if (!value || iupStrToDoubleDouble(value, &Cmin, &Cmax, ':') != 2) { if (coloraxisticks && tolower(*coloraxisticks) == 'x') { Cmin = Min.x; Cmax = Max.x; } else if (coloraxisticks && tolower(*coloraxisticks) == 'y') { Cmin = Min.y; Cmax = Max.y; } else { // By default set CMin-Max to Z Min-Max Cmin = Min.z; Cmax = Max.z; } } gr->SetRange('c', Cmin, Cmax); if (coloraxisticks && tolower(*coloraxisticks) == 'x') iMglPlotConfigAxisTicks(ih, gr, 'c', ih->data->axisX, Cmin, Cmax); else if (coloraxisticks && tolower(*coloraxisticks) == 'y') iMglPlotConfigAxisTicks(ih, gr, 'c', ih->data->axisY, Cmin, Cmax); else iMglPlotConfigAxisTicks(ih, gr, 'c', ih->data->axisZ, Cmin, Cmax); // Origin gr->SetOrigin(ih->data->axisX.axOrigin, ih->data->axisY.axOrigin, ih->data->axisZ.axOrigin); // Scale if (ih->data->axisX.axScale || ih->data->axisY.axScale || ih->data->axisZ.axScale) gr->SetFunc(ih->data->axisX.axScale, ih->data->axisY.axScale, ih->data->axisZ.axScale, NULL); else gr->SetFunc(NULL, NULL, NULL, NULL); } static void iMglPlotDrawAxisLabel(Ihandle* ih, mglGraph *gr, char dir, Iaxis& axis) { char attrib[11] = "AXS_?LABEL"; attrib[4] = dir; iupStrUpper(attrib, attrib); char* label = iupAttribGetStr(ih, attrib); if (label) { gr->SetRotatedText(axis.axLabelRotation); iMglPlotConfigFont(ih, gr, &axis.axColor, axis.axLabelFontStyle, axis.axLabelFontSizeFactor); gr->Label(dir, label, (mreal)axis.axLabelPos, ""); gr->SetRotatedText(false); } } static void iMglPlotConfigAxisTicksNames(Ihandle* ih, mglGraph *gr, bool set) { IdataSet* ds = &ih->data->dataSet[0]; // Allow names only for the first dataset if (ds->dsNames) { // TODO: TicksVal should follow ticks spacing configuration if (set) { char** dsNames = (char**)iupArrayGetData(ds->dsNames); int count = iupArrayCount(ds->dsNames); int i, total_size = 0; for (i = 0; i < count; i++) total_size += (int)strlen(dsNames[i]) + 1; char* labels = new char[total_size + 1]; labels[0] = 0; for (i = 0; i < count; i++) { strcat(labels, dsNames[i]); strcat(labels, "\n"); } gr->SetTicksVal('x', labels); delete[] labels; } else gr->SetTicksVal('x', (wchar_t*)NULL); } } static void iMglPlotConfigAxisTicksLen(mglGraph *gr, Iaxis& axis) { if (!axis.axTickAutoSize) gr->SetTickLen(-axis.axTickMajorSize, axis.axTickMinorSizeFactor); else gr->SetTickLen(-0.02, 1.0); } static void iMglPlotDrawAxis(Ihandle* ih, mglGraph *gr, char dir, Iaxis& axis) { // Must be set here, because there is only one for all the axis. iMglPlotConfigAxisTicksLen(gr, axis); // Must be reset after configuring the ticks if (dir == 'x') iMglPlotConfigAxisTicksNames(ih, gr, true); // Configure ticks values rotation along axis gr->SetRotatedText(axis.axTickValuesRotation); char style[64] = ""; iMglPlotAddStyleColor(ih, style, axis.axColor); iMglPlotConfigFont(ih, gr, &axis.axColor, axis.axTickFontStyle, axis.axTickFontSizeFactor); // Draw the axis, ticks and ticks values int i = 0; char sdir[10]; sdir[i++] = dir; if (!axis.axTickShowValues) sdir[i++] = '_'; if (axis.axShowArrow) sdir[i++] = 'T'; if (axis.axReverse) sdir[i++] = '^'; sdir[i] = 0; /* TODO - more ticks options  ‘XYZ' for drawing axis in corresponding direction but with inverted positions of labels;  ‘U' for disabling rotation of tick labels;  ‘a' for forced adjusting of axis ticks. gr->SetOriginTick(axis.axTickShowOrigin); gr->SetTickRotate(false); */ // Spacing between ticks and ticks labels gr->SetTickShift(mglPoint(0.1, 0.1, 0.1)); gr->Axis(sdir, style); // Reset to default if (dir == 'x') iMglPlotConfigAxisTicksNames(ih, gr, false); gr->SetRotatedText(false); } static void iMglPlotDrawAxes(Ihandle* ih, mglGraph *gr) { // Draw axes lines, ticks and ticks labels if (ih->data->axisX.axShow) { iMglPlotDrawAxis(ih, gr, 'x', ih->data->axisX); iMglPlotDrawAxisLabel(ih, gr, 'x', ih->data->axisX); } if(ih->data->axisY.axShow) { iMglPlotDrawAxis(ih, gr, 'y', ih->data->axisY); iMglPlotDrawAxisLabel(ih, gr, 'y', ih->data->axisY); } if (ih->data->axisZ.axShow && iMglPlotIsView3D(ih)) { iMglPlotDrawAxis(ih, gr, 'z', ih->data->axisZ); iMglPlotDrawAxisLabel(ih, gr, 'z', ih->data->axisZ); } if (iupAttribGetBoolean(ih, "COLORBAR")) { char style[64] = ""; char* value = iupAttribGetStr(ih, "COLORBARPOS"); if (iupStrEqualNoCase(value, "LEFT")) style[0] = '<'; else if (iupStrEqualNoCase(value, "TOP")) style[0] = '^'; else if (iupStrEqualNoCase(value, "BOTTOM")) style[0] = '_'; else style[0] = '>'; // RIGHT style[1] = 0; // Can NOT configure Axis color or it will affect the colors of the colorbar if (style[0] == '>' || style[0] == '<') iMglPlotConfigFont(ih, gr, &ih->data->axisX.axColor, ih->data->axisX.axTickFontStyle, ih->data->axisX.axTickFontSizeFactor); else iMglPlotConfigFont(ih, gr, &ih->data->axisY.axColor, ih->data->axisY.axTickFontStyle, ih->data->axisY.axTickFontSizeFactor); gr->Colorbar(style); } } static void iMglPlotDrawGrid(Ihandle* ih, mglGraph *gr) { char style[64] = ""; iMglPlotAddStyleColor(ih, style, ih->data->gridColor); iMglPlotAddStyleLine(style, ih->data->gridLineStyle, 1); char grid[10]; iupStrLower(grid, ih->data->gridShow); gr->Grid(grid, style); } static void iMglPlotDrawBox(Ihandle* ih, mglGraph *gr) { char style[64] = ""; iMglPlotAddStyleColor(ih, style, ih->data->boxColor); gr->Box(style, ih->data->boxTicks); } static char* iMglPlotMakeFormatString(double inValue, double range) { if (inValue<0) inValue = range/(-inValue); if (inValue > 1.0e4 || inValue < 1.0e-3) return "%.1e"; else { int thePrecision = 0; if (inValue<1) { double theSpan = inValue; while (theSpan<1 && thePrecision<10) { thePrecision++; theSpan *= 10; } if (thePrecision<10) thePrecision++; } switch (thePrecision) { case 1: return "%.1f"; case 2: return "%.2f"; case 3: return "%.3f"; case 4: return "%.4f"; case 5: return "%.5f"; case 6: return "%.6f"; case 7: return "%.7f"; case 8: return "%.8f"; case 9: return "%.9f"; default: return "%.0f"; } } } static void iMglPlotDrawValues(Ihandle* ih, IdataSet* ds, mglGraph *gr) { int i; char style[64] = ""; char text[256]; char format[256]; mglPoint p; char* xformat = iupAttribGetStr(ih, "AXS_XTICKFORMAT"); char* yformat = iupAttribGetStr(ih, "AXS_YTICKFORMAT"); char* zformat = iupAttribGetStr(ih, "AXS_ZTICKFORMAT"); if (!xformat) xformat = iMglPlotMakeFormatString(ih->data->axisX.axTickMajorSpan, ih->data->axisX.axMax - ih->data->axisX.axMin); if (!yformat) yformat = iMglPlotMakeFormatString(ih->data->axisY.axTickMajorSpan, ih->data->axisY.axMax - ih->data->axisY.axMin); if (!zformat) zformat = iMglPlotMakeFormatString(ih->data->axisZ.axTickMajorSpan, ih->data->axisZ.axMax - ih->data->axisZ.axMin); iMglPlotAddStyleColor(ih, style, ds->dsColor); strcat(style, ":L"); iMglPlotConfigFont(ih, gr, NULL, ih->data->legendFontStyle, ih->data->legendFontSizeFactor); gr->SetRotatedText(true); double* dsXPoints = ds->dsX->a; if (ds->dsDim == 3) { double* dsYPoints = ds->dsY->a; double* dsZPoints = ds->dsZ->a; mglPoint d = mglPoint(ih->data->axisX.axMax-ih->data->axisX.axMin, ih->data->axisY.axMax-ih->data->axisY.axMin, ih->data->axisZ.axMax-ih->data->axisZ.axMin); sprintf(format, "(%s, %s, %s)", xformat, yformat, zformat); for(i = 0; i < ds->dsCount; i++) { sprintf(text, format, dsXPoints[i], dsYPoints[i], dsZPoints[i]); p = mglPoint(dsXPoints[i], dsYPoints[i], dsZPoints[i]); gr->Puts(p, p + d, text, style); } } else if (ds->dsDim == 2) { double* dsYPoints = ds->dsY->a; mglPoint d = mglPoint(ih->data->axisX.axMax - ih->data->axisX.axMin, ih->data->axisY.axMax - ih->data->axisY.axMin); sprintf(format, "(%s, %s)", xformat, yformat); for(i = 0; i < ds->dsCount; i++) { sprintf(text, format, dsXPoints[i], dsYPoints[i]); p = mglPoint(dsXPoints[i], dsYPoints[i]); gr->Puts(p, p + d, text, style); } } else { sprintf(format, "(%%d, %s)", xformat); mglPoint d = mglPoint(ih->data->axisX.axMax-ih->data->axisX.axMin, ih->data->axisY.axMax-ih->data->axisY.axMin); for(i = 0; i < ds->dsCount; i++) { sprintf(text, format, i, dsXPoints[i]); p = mglPoint((double)i, dsXPoints[i]); gr->Puts(p, p + d, text, style); } } gr->SetRotatedText(false); } static void iMglPlotConfigDataGrid(mglGraph *gr, IdataSet* ds, char* style) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); strcat(style, "#"); // grid } static void iMglPlotConfigColorScheme(Ihandle* ih, char* style) { char* value = iupAttribGetStr(ih, "COLORSCHEME"); if (value) { strcpy(style, value); strcat(style, ":"); } } static void iMglPlotDrawVolumetricData(Ihandle* ih, mglGraph *gr, IdataSet* ds) { char style[64] = ""; char* value; // All plots here are affected by ColorScheme iMglPlotConfigColorScheme(ih, style); if (iupStrEqualNoCase(ds->dsMode, "VOLUME_ISOSURFACE")) { if (iupAttribGetBoolean(ih, "DATAGRID")) // Default false iMglPlotConfigDataGrid(gr, ds, style); // Here means wire value = iupAttribGet(ih, "ISOVALUE"); if (value) { double isovalue; if (iupStrToDouble(value, &isovalue)) gr->Surf3(isovalue, *ds->dsX, style); // only 1 isosurface } else { int isocount = iupAttribGetInt(ih, "ISOCOUNT"); //Default 3 char opt[100]; sprintf(opt, "value %d;", isocount); gr->Surf3(*ds->dsX, style, opt); // plots N isosurfaces, from Cmin to Cmax } } else if (iupStrEqualNoCase(ds->dsMode, "VOLUME_DENSITY")) { if (iupAttribGetBoolean(ih, "DATAGRID")) // Default false iMglPlotConfigDataGrid(gr, ds, style); // Here means wire char* slicedir = iupAttribGetStr(ih, "SLICEDIR"); //Default "XYZ" int project = iupAttribGetBoolean(ih, "PROJECT"); //Default false if (project) { double valx = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEX"); double valy = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEY"); double valz = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEZ"); if (tolower(*slicedir)=='x') { gr->DensX(ds->dsX->Sum("x"), style, valx); slicedir++; } if (tolower(*slicedir)=='y') { gr->DensY(ds->dsX->Sum("y"), style, valy); slicedir++; } if (tolower(*slicedir)=='z') { gr->DensZ(ds->dsX->Sum("z"), style, valz); slicedir++; } } else { double slicex = iupAttribGetDouble(ih, "SLICEX"); //Default -1 (central) double slicey = iupAttribGetDouble(ih, "SLICEY"); //Default -1 (central) double slicez = iupAttribGetDouble(ih, "SLICEZ"); //Default -1 (central) if (tolower(*slicedir) == 'x') { strcat(style, "x"); gr->Dens3(*ds->dsX, style, slicex); slicedir++; } if (tolower(*slicedir) == 'y') { strcat(style, "y"); gr->Dens3(*ds->dsX, style, slicey); slicedir++; } if (tolower(*slicedir) == 'z') { strcat(style, "z"); gr->Dens3(*ds->dsX, style, slicez); slicedir++; } } } else if (iupStrEqualNoCase(ds->dsMode, "VOLUME_CONTOUR")) { if (iupAttribGetBoolean(ih, "DATAGRID")) iMglPlotConfigDataGrid(gr, ds, style); // Here means wire int contourcount = iupAttribGetInt(ih, "CONTOURCOUNT"); //Default 7, plots N countours, from Cmin to Cmax char opt[100]; sprintf(opt, "value %d;", contourcount); int countourfilled = iupAttribGetBoolean(ih, "CONTOURFILLED"); //Default false char* slicedir = iupAttribGetStr(ih, "SLICEDIR"); //Default "XYZ" int project = iupAttribGetBoolean(ih, "PROJECT"); //Default false if (project) { double valx = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEX"); double valy = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEY"); double valz = iMglPlotGetAttribDoubleNAN(ih, "PROJECTVALUEZ"); if (countourfilled) { if (tolower(*slicedir) == 'x') { gr->ContFX(ds->dsX->Sum("x"), style, valx, opt); slicedir++; } if (tolower(*slicedir) == 'y') { gr->ContFY(ds->dsX->Sum("y"), style, valy, opt); slicedir++; } if (tolower(*slicedir) == 'z') { gr->ContFZ(ds->dsX->Sum("z"), style, valz, opt); slicedir++; } } else { if (tolower(*slicedir) == 'x') { gr->ContX(ds->dsX->Sum("x"), style, valx, opt); slicedir++; } if (tolower(*slicedir) == 'y') { gr->ContY(ds->dsX->Sum("y"), style, valy, opt); slicedir++; } if (tolower(*slicedir) == 'z') { gr->ContZ(ds->dsX->Sum("z"), style, valz, opt); slicedir++; } } } else { double slicex = iupAttribGetDouble(ih, "SLICEX"); //Default -1 (central) double slicey = iupAttribGetDouble(ih, "SLICEY"); //Default -1 (central) double slicez = iupAttribGetDouble(ih, "SLICEZ"); //Default -1 (central) if (countourfilled) { if (tolower(*slicedir) == 'x') { strcat(style, "x"); gr->ContF3(*ds->dsX, style, slicex, opt); slicedir++; } if (tolower(*slicedir) == 'y') { strcat(style, "y"); gr->ContF3(*ds->dsX, style, slicey, opt); slicedir++; } if (tolower(*slicedir) == 'z') { strcat(style, "z"); gr->ContF3(*ds->dsX, style, slicez, opt); slicedir++; } } else { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); if (tolower(*slicedir) == 'x') { strcat(style, "x"); gr->Cont3(*ds->dsX, style, slicex, opt); slicedir++; } if (tolower(*slicedir) == 'y') { strcat(style, "y"); gr->Cont3(*ds->dsX, style, slicey, opt); slicedir++; } if (tolower(*slicedir) == 'z') { strcat(style, "z"); gr->Cont3(*ds->dsX, style, slicez, opt); slicedir++; } } } } else if (iupStrEqualNoCase(ds->dsMode, "VOLUME_CLOUD")) { int low = iupAttribGetBoolean(ih, "CLOUDLOW"); //Default false if (low) strcat(style, "."); gr->Cloud(*ds->dsX, style, "-1"); // Use AlphaDef } } static void iMglPlotDrawPlanarData(Ihandle* ih, mglGraph *gr, IdataSet* ds) { char style[64] = ""; // All plots here are affected by ColorScheme iMglPlotConfigColorScheme(ih, style); if (iupStrEqualNoCase(ds->dsMode, "PLANAR_MESH")) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); gr->Mesh(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_FALL")) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); char* falldir = iupAttribGetStr(ih, "DIR"); //Default "Y" if (tolower(*falldir) == 'x') { style[0] = 'x'; style[1] = 0; } gr->Fall(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_BELT")) { char* beltdir = iupAttribGetStr(ih, "DIR"); //Default "Y" if (tolower(*beltdir) == 'x') { style[0] = 'x'; style[1] = 0; } gr->Belt(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_SURFACE")) { if (iupAttribGetBoolean(ih, "DATAGRID")) // Default false iMglPlotConfigDataGrid(gr, ds, style); gr->Surf(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_BOXES")) { if (iupAttribGetBoolean(ih, "DATAGRID")) // Default false iMglPlotConfigDataGrid(gr, ds, style); // Here means box lines gr->Boxs(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_TILE")) { gr->Tile(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_DENSITY")) { gr->Dens(*ds->dsX, style, ""); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_CONTOUR")) { int contourcount = iupAttribGetInt(ih, "CONTOURCOUNT"); //Default 7, plots N countours, from Cmin to Cmax int countourfilled = iupAttribGetBoolean(ih, "CONTOURFILLED"); //Default false char opt[100]; sprintf(opt, "value %d;", contourcount); if (countourfilled) gr->ContF(*ds->dsX, style, opt); else { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); char* countourlabels = iupAttribGetStr(ih, "CONTOURLABELS"); //Default NULL if (iupStrEqualNoCase(countourlabels, "BELLOW")) strcat(style, "t"); else if (iupStrEqualNoCase(countourlabels, "ABOVE")) strcat(style, "T"); gr->Cont(*ds->dsX, style, opt); } } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_AXIALCONTOUR")) { int axialcount = iupAttribGetInt(ih, "AXIALCOUNT"); //Default 3, plots N countours, from Cmin to Cmax char opt[100]; sprintf(opt, "value %d;", axialcount); gr->Axial(*ds->dsX, style, opt); } else if (iupStrEqualNoCase(ds->dsMode, "PLANAR_GRADIENTLINES")) { int gradlinescount = iupAttribGetInt(ih, "GRADLINESCOUNT"); //Default 5 char opt[100]; sprintf(opt, "value %d;", gradlinescount); gr->Grad(*ds->dsX, style, opt); } } static void iMglPlotDrawLinearData(Ihandle* ih, mglGraph *gr, IdataSet* ds) { char style[64] = ""; iMglPlotAddStyleColor(ih, style, ds->dsColor); if (iupStrEqualNoCase(ds->dsMode, "LINE") || iupStrEqualNoCase(ds->dsMode, "MARKLINE") || iupStrEqualNoCase(ds->dsMode, "MARK")) { if (!iupStrEqualNoCase(ds->dsMode, "LINE")) // same as setting marks=yes ds->dsShowMarks = true; if (iupStrEqualNoCase(ds->dsMode, "MARK")) // Same as setting linestyle=none ds->dsLineStyle = ' '; // No line // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); if (ds->dsDim == 3) gr->Plot(*ds->dsX, *ds->dsY, *ds->dsZ, style); else if (ds->dsDim == 2) gr->Plot(*ds->dsX, *ds->dsY, style, 0); else gr->Plot(*ds->dsX, style, 0); // At Z=0 } else if (iupStrEqualNoCase(ds->dsMode, "RADAR")) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); char opt[100] = ""; if (iupAttribGet(ih, "RADARSHIFT")) { double radarshift = iupAttribGetDouble(ih, "RADARSHIFT"); // Default -1 sprintf(opt, "value %g;", radarshift); } if (iupAttribGetBoolean(ih, "DATAGRID")) //Default false iMglPlotConfigDataGrid(gr, ds, style); gr->Radar(*ds->dsX, style, opt); } else if (iupStrEqualNoCase(ds->dsMode, "AREA")) { // NOT affected by SetLineMark if (ds->dsDim == 3) gr->Area(*ds->dsX, *ds->dsY, *ds->dsZ, style); else if (ds->dsDim == 2) gr->Area(*ds->dsX, *ds->dsY, style, 0); else gr->Area(*ds->dsX, style, 0); } else if (iupStrEqualNoCase(ds->dsMode, "BAR")) { // NOT affected by SetLineMark strcat(style, "^"); // center align the bar if (iupAttribGetBoolean(ih, "DATAGRID")) //Default false iMglPlotConfigDataGrid(gr, ds, style); double barwidth = iupAttribGetDouble(ih, "BARWIDTH"); // Default 0.7 if (barwidth <= 0) barwidth = 0.7; gr->SetBarWidth(barwidth); // To avoid hole bars clipped when touching the bounding box gr->SetCut(false); if (ds->dsDim == 3) gr->Bars(*ds->dsX, *ds->dsY, *ds->dsZ, style); else if (ds->dsDim == 2) gr->Bars(*ds->dsX, *ds->dsY, style, 0); else gr->Bars(*ds->dsX, style, 0); gr->SetCut(true); } else if (iupStrEqualNoCase(ds->dsMode, "BARHORIZONTAL")) { // NOT affected by SetLineMark if (iupAttribGetBoolean(ih, "DATAGRID")) //Default false iMglPlotConfigDataGrid(gr, ds, style); double barwidth = iupAttribGetDouble(ih, "BARWIDTH"); // Default 0.7 if (barwidth <= 0) barwidth = 0.7; gr->SetBarWidth(barwidth); // To avoid hole bars clipped when touching the bounding box gr->SetCut(false); if (ds->dsDim == 2) gr->Barh(*ds->dsY, *ds->dsX, style, 0); else gr->Barh(*ds->dsX, style, 0); gr->SetCut(true); } else if (iupStrEqualNoCase(ds->dsMode, "STEP")) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); if (ds->dsDim == 3) gr->Step(*ds->dsX, *ds->dsY, *ds->dsZ, style); else if (ds->dsDim == 2) gr->Step(*ds->dsX, *ds->dsY, style, 0); else gr->Step(*ds->dsX, style, 0); } else if (iupStrEqualNoCase(ds->dsMode, "STEM")) { // Affected by SetLineMark iMglPlotConfigDataSetLineMark(ds, gr, style); if (ds->dsDim == 3) gr->Stem(*ds->dsX, *ds->dsY, *ds->dsZ, style); else if (ds->dsDim == 2) gr->Stem(*ds->dsX, *ds->dsY, style, 0); else gr->Stem(*ds->dsX, style, 0); } else if (iupStrEqualNoCase(ds->dsMode, "CHART")) { // NOT affected by SetLineMark style[0] = 0; // Affected by ColorScheme iMglPlotConfigColorScheme(ih, style); if (iupAttribGetBoolean(ih, "DATAGRID")) //Default false iMglPlotConfigDataGrid(gr, ds, style); int piechart = iupAttribGetBoolean(ih, "PIECHART"); //Default false if (piechart) { //TODO: this equation works only if x in the interval [-1, 1] gr->SetFunc("(y+1)/2*cos(pi*x)", "(y+1)/2*sin(pi*x)"); // This box has to be here, so it will be affected by the transformation if (ih->data->Box) iMglPlotDrawBox(ih, gr); gr->Chart(*ds->dsX, style); gr->SetFunc(NULL, NULL); } else gr->Chart(*ds->dsX, style); } else if (iupStrEqualNoCase(ds->dsMode, "CRUST")) { if (ds->dsDim == 3) { // NOT affected by SetLineMark // NOT affected by StyleColor style[0] = 0; // Affected by ColorScheme iMglPlotConfigColorScheme(ih, style); if (iupAttribGetBoolean(ih, "DATAGRID")) //Default false iMglPlotConfigDataGrid(gr, ds, style); gr->Crust(*ds->dsX, *ds->dsY, *ds->dsZ, style, ""); } } else if (iupStrEqualNoCase(ds->dsMode, "DOTS")) { if (ds->dsDim == 3) { // NOT affected by SetLineMark // NOT affected by StyleColor style[0] = 0; // Affected by ColorScheme iMglPlotConfigColorScheme(ih, style); gr->Dots(*ds->dsX, *ds->dsY, *ds->dsZ, style); } } } static void iMglPlotDrawData(Ihandle* ih, mglGraph *gr) { int i; for(i = 0; i < ih->data->dataSetCount; i++) { IdataSet* ds = &ih->data->dataSet[i]; if (iMglPlotIsVolumetricData(ds)) iMglPlotDrawVolumetricData(ih, gr, ds); else if (iMglPlotIsPlanarData(ds)) iMglPlotDrawPlanarData(ih, gr, ds); else iMglPlotDrawLinearData(ih, gr, ds); if(ds->dsShowValues && !iMglPlotIsPlanarOrVolumetricData(ds)) iMglPlotDrawValues(ih, ds, gr); /* Print values near the samples */ } } static void iMglPlotDrawLegend(Ihandle* ih, mglGraph *gr) { int i; char style[64] = ""; gr->ClearLegend(); for(i = 0; i < ih->data->dataSetCount; i++) { IdataSet* ds = &ih->data->dataSet[i]; style[0] = 0; iMglPlotConfigDataSetLineMark(ds, gr, style); iMglPlotAddStyleColor(ih, style, ds->dsColor); gr->AddLegend(ds->dsLegend, style); } style[0] = 0; if (ih->data->legendBox) { style[0] = '#'; style[1] = 0; } // Draw legend of accumulated strings iMglPlotAddStyleColor(ih, style, ih->data->bgColor); // background iMglPlotAddStyleColor(ih, style, ih->data->legendColor); // text iMglPlotConfigFont(ih, gr, NULL, ih->data->legendFontStyle, ih->data->legendFontSizeFactor); gr->Legend(ih->data->legendPosition, style, "value 0.05;"); } static void iMglPlotDrawTitle(Ihandle* ih, mglGraph *gr, const char* title) { char style[64] = ""; iMglPlotAddStyleColor(ih, style, ih->data->titleColor); iMglPlotConfigFont(ih, gr, &ih->data->titleColor, ih->data->titleFontStyle, ih->data->titleFontSizeFactor); gr->Title(title, style); } static void iMglPlotConfigPlotArea(Ihandle* ih, mglGraph *gr) { char style[64] = ""; int i = 0; char* colorbar_pos = NULL; if (iupAttribGetBoolean(ih, "COLORBAR")) colorbar_pos = iupAttribGetStr(ih, "COLORBARPOS"); if (iupAttribGetStr(ih, "TITLE")) style[i++] = 'T'; if (iupAttribGetBoolean(ih, "MARGINTOP") || iupStrEqualNoCase(colorbar_pos, "TOP")) style[i++] = '^'; if (iupAttribGetBoolean(ih, "MARGINBOTTOM") || iupStrEqualNoCase(colorbar_pos, "BOTTOM")) style[i++] = '_'; if (iupAttribGetBoolean(ih, "MARGINLEFT") || iupStrEqualNoCase(colorbar_pos, "LEFT")) style[i++] = '<'; if (iupAttribGetBoolean(ih, "MARGINRIGHT") || iupStrEqualNoCase(colorbar_pos, "RIGHT")) style[i++] = '>'; style[i] = 0; gr->SubPlot(1, 1, 0, style); } static void iMglPlotConfigView(Ihandle* ih, mglGraph *gr) { // Transparency gr->Alpha(true); // Necessary so Anti-alias can work. if (ih->data->transparent) gr->SetAlphaDef(ih->data->alpha); // Should be used only if transparent is enabled else gr->SetAlphaDef(1.0); // Zoom and Pan gr->Zoom(ih->data->x1, ih->data->y1, ih->data->x2, ih->data->y2); if (iMglPlotIsView3D(ih)) { if (iupAttribGetBoolean(ih, "LIGHT")) /* Default: FALSE */ gr->Light(true); else gr->Light(false); // Notice that rotZ is the second parameter gr->Rotate(ih->data->rotX, ih->data->rotZ, ih->data->rotY); } } static void iMglPlotDrawPlot(Ihandle* ih, mglGraph *gr) { // Since this function will be used to draw on screen and // on metafile and bitmaps, all mglGraph control must be done here // and can NOT be done inside the attribute methods gr->DefaultPlotParam(); gr->SetWarn(0, ""); /* Clear */ gr->Clf(ih->data->bgColor.r, ih->data->bgColor.g, ih->data->bgColor.b); iMglPlotConfigPlotArea(ih, gr); iMglPlotConfigView(ih, gr); iMglPlotConfigFontDef(ih, gr, IupGetAttribute(ih, "FONT")); iMglPlotConfigAxesRange(ih, gr); iupAttribSet(ih, "_IUP_MGLPLOT_GRAPH", (char*)gr); IFn cb = IupGetCallback(ih, "PREDRAW_CB"); if (cb) cb(ih); iMglPlotDrawAxes(ih, gr); if(ih->data->gridShow) iMglPlotDrawGrid(ih, gr); int piechart = iupAttribGetBoolean(ih, "PIECHART"); //Default false if (ih->data->Box && !piechart) iMglPlotDrawBox(ih, gr); iMglPlotDrawData(ih, gr); if(ih->data->legendShow) iMglPlotDrawLegend(ih, gr); char* value = iupAttribGetStr(ih, "TITLE"); if (value) iMglPlotDrawTitle(ih, gr, value); cb = IupGetCallback(ih, "POSTDRAW_CB"); if (cb) cb(ih); iupAttribSet(ih, "_IUP_MGLPLOT_GRAPH", NULL); } static void iMglPlotRepaint(Ihandle* ih, int force, int flush) { if (!IupGLIsCurrent(ih)) force = 1; IupGLMakeCurrent(ih); mglGraph* gr = ih->data->mgl; if (force || ih->data->redraw) { /* update render */ iMglPlotDrawPlot(ih, gr); /* Draw the graphics plot */ gr->Finish(); ih->data->redraw = false; } if (flush) { if (!ih->data->opengl) { const unsigned char *rgb = gr->GetRGB(); if (rgb) glDrawPixels(ih->data->w, ih->data->h, GL_RGB, GL_UNSIGNED_BYTE, rgb); } IupGLSwapBuffers(ih); } } /****************************************************************************** Attribute Methods ******************************************************************************/ static int iMglPlotSetColor(Ihandle* ih, const char* value, mglColor& color) { unsigned char rr, gg, bb, aa = 255; if (!value) { color.Set(NAN, NAN, NAN); ih->data->redraw = true; } else if (iupStrToRGBA(value, &rr, &gg, &bb, &aa)) { color.Set(iRecon(rr), iRecon(gg), iRecon(bb), iRecon(aa)); ih->data->redraw = true; } return 0; } static char* iMglPlotReturnColor(const mglColor& color) { if (color.a < 1) return iupStrReturnRGBA(iQuant(color.r), iQuant(color.g), iQuant(color.b), iQuant(color.a)); else return iupStrReturnRGB(iQuant(color.r), iQuant(color.g), iQuant(color.b)); } static int iMglPlotSetBoolean(Ihandle* ih, const char* value, bool& num) { bool old_num = num; if (iupStrBoolean(value)) num = true; else num = false; if (old_num != num) ih->data->redraw = true; return 0; } static int iMglPlotSetInt(Ihandle* ih, const char* value, int& num) { int old_num = num; iupStrToInt(value, &num); if (old_num != num) ih->data->redraw = true; return 0; } static int iMglPlotSetDouble(Ihandle* ih, const char* value, double& num, double num_def) { double old_num = num; if (!value) num = num_def; else iupStrToDouble(value, &num); if (old_num != num) ih->data->redraw = true; return 0; } static int iMglPlotSetResetAttrib(Ihandle* ih, const char* value) { (void)value; /* not used */ iMglPlotReset(ih); // Some attributes are stored in the hash table iupAttribSet(ih, "TITLE", NULL); iupAttribSet(ih, "DATAGRID", NULL); iupAttribSet(ih, "GRADLINESCOUNT", NULL); iupAttribSet(ih, "AXIALCOUNT", NULL); iupAttribSet(ih, "CONTOURFILLED", NULL); iupAttribSet(ih, "CONTOURLABELS", NULL); iupAttribSet(ih, "CONTOURCOUNT", NULL); iupAttribSet(ih, "DIR", NULL); iupAttribSet(ih, "CLOUDLOW", NULL); iupAttribSet(ih, "SLICEX", NULL); iupAttribSet(ih, "SLICEY", NULL); iupAttribSet(ih, "SLICEZ", NULL); iupAttribSet(ih, "SLICEDIR", NULL); iupAttribSet(ih, "PROJECTVALUEX", NULL); iupAttribSet(ih, "PROJECTVALUEY", NULL); iupAttribSet(ih, "PROJECTVALUEZ", NULL); iupAttribSet(ih, "PROJECT", NULL); iupAttribSet(ih, "ISOCOUNT", NULL); iupAttribSet(ih, "BARWIDTH", NULL); iupAttribSet(ih, "RADARSHIFT", NULL); iupAttribSet(ih, "PIECHART", NULL); iupAttribSet(ih, "CRUSTRADIUS", NULL); iupAttribSet(ih, "LIGHT", NULL); iupAttribSet(ih, "COLORSCHEME", NULL); iupAttribSet(ih, "COLORBAR", NULL); iupAttribSet(ih, "COLORBARPOS", NULL); iupAttribSet(ih, "COLORBARRANGE", NULL); iupAttribSet(ih, "COLORBARAXISTICKS", NULL); iupAttribSet(ih, "AXS_XLABEL", NULL); iupAttribSet(ih, "AXS_YLABEL", NULL); iupAttribSet(ih, "AXS_ZLABEL", NULL); iupAttribSet(ih, "AXS_XTICKFORMAT", NULL); iupAttribSet(ih, "AXS_YTICKFORMAT", NULL); iupAttribSet(ih, "AXS_ZTICKFORMAT", NULL); ih->data->redraw = true; return 0; } static int iMglPlotSetRedrawAttrib(Ihandle* ih, const char* value) { (void)value; /* not used */ iMglPlotRepaint(ih, 1, 1); /* force a full redraw here */ return 0; } static int iMglPlotSetBGColorAttrib(Ihandle* ih, const char* value) { iMglPlotSetColor(ih, value, ih->data->bgColor); return 1; } static char* iMglPlotGetBGColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->bgColor); } static int iMglPlotSetFGColorAttrib(Ihandle* ih, const char* value) { iMglPlotSetColor(ih, value, ih->data->fgColor); return 1; } static char* iMglPlotGetFGColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->fgColor); } static int iMglPlotSetTitleFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->titleFontSizeFactor, 1.0); } static char* iMglPlotGetTitleFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->titleFontSizeFactor); } static int iMglPlotSetFontStyle(Ihandle* ih, const char* value, char* fontstyle) { fontstyle[0] = 0; if (iMglPlotAddStyleFont(fontstyle, value)) ih->data->redraw = true; return 0; } static char* iMglPlotGetFontStyle(const char* fontstyle) { char* str = iupStrGetMemory(100); if (strchr(fontstyle, 'r')) strcpy(str, "Plain "); else { if (strchr(fontstyle, 'b')) strcpy(str, "Bold "); if (strchr(fontstyle, 'i')) strcpy(str, "Italic "); } if (strchr(fontstyle, 'w')) strcpy(str, "Wired "); if (strchr(fontstyle, 'o')) strcpy(str, "Strikeout "); if (strchr(fontstyle, 'u')) strcpy(str, "Underline "); if (strchr(fontstyle, 'L')) strcpy(str, "Left "); else if (strchr(fontstyle, 'R')) strcpy(str, "Right "); else if (strchr(fontstyle, 'C')) strcpy(str, "Center "); if (str[0] != 0) return str; else return NULL; } static int iMglPlotSetTitleFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->titleFontStyle); } static char* iMglPlotGetTitleFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->titleFontStyle); } static int iMglPlotSetTitleColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->titleColor); } static char* iMglPlotGetTitleColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->titleColor); } static int iMglPlotSetLegendFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->legendFontSizeFactor, 1.0); } static char* iMglPlotGetLegendFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->legendFontStyle); } static char* iMglPlotGetLegendFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->legendFontSizeFactor); } static int iMglPlotSetLegendFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->legendFontStyle); } static int iMglPlotSetLegendShowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->legendShow); } static char* iMglPlotGetLegendShowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->legendShow); } static int iMglPlotSetLegendBoxAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->legendBox); } static char* iMglPlotGetLegendBoxAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->legendBox); } static int iMglPlotSetLegendPosAttrib(Ihandle* ih, const char* value) { if (iupStrEqualNoCase(value, "TOPLEFT")) ih->data->legendPosition = IUP_MGLPLOT_TOPLEFT; else if (iupStrEqualNoCase(value, "BOTTOMLEFT")) ih->data->legendPosition = IUP_MGLPLOT_BOTTOMLEFT; else if (iupStrEqualNoCase(value, "BOTTOMRIGHT")) ih->data->legendPosition = IUP_MGLPLOT_BOTTOMRIGHT; else ih->data->legendPosition = IUP_MGLPLOT_TOPRIGHT; ih->data->redraw = true; return 0; } static char* iMglPlotGetLegendPosAttrib(Ihandle* ih) { const char* legendpos_str[4] = {"BOTTOMLEFT", "BOTTOMRIGHT", "TOPLEFT", "TOPRIGHT"}; return (char*)legendpos_str[ih->data->legendPosition]; } static int iMglPlotSetLegendColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->legendColor); } static char* iMglPlotGetLegendColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->legendColor); } static int iMglPlotSetGridColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->gridColor); } static char* iMglPlotGetGridColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->gridColor); } static int iMglPlotSetBoxColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->boxColor); } static char* iMglPlotGetBoxColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->boxColor); } static int iMglPlotSetLineStyle(Ihandle* ih, const char* value, char &linestyle) { char old_linestyle = linestyle; if (!value || iupStrEqualNoCase(value, "CONTINUOUS") || iupStrEqualNoCase(value, "SOLID")) linestyle = '-'; else if (iupStrEqualNoCase(value, "LONGDASHED")) linestyle = '|'; else if (iupStrEqualNoCase(value, "DASHED")) linestyle = ';'; else if (iupStrEqualNoCase(value, "SMALLDASHED")) linestyle = '='; else if (iupStrEqualNoCase(value, "DOTTED")) linestyle = ':'; else if (iupStrEqualNoCase(value, "DASH_DOT")) linestyle = 'j'; else if (iupStrEqualNoCase(value, "SMALLDASH_DOT") || iupStrEqualNoCase(value, "DASH_DOT_DOT")) // for IUP compatibility linestyle = 'i'; else if (iupStrEqualNoCase(value, "NONE")) linestyle = ' '; else linestyle = '-'; /* reset to default */ if (old_linestyle != linestyle) ih->data->redraw = true; return 0; } static char* iMglPlotGetLineStyle(char linestyle) { switch(linestyle) { case ' ': return "NONE"; case '|': return "LONGDASHED"; case ';': return "DASHED"; case '=': return "SMALLDASHED"; case ':': return "DOTTED"; case 'j': return "DASH_DOT"; case 'i': return "SMALLDASH_DOT"; default: return "CONTINUOUS"; } } static int iMglPlotSetGridLineStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetLineStyle(ih, value, ih->data->gridLineStyle); } static char* iMglPlotGetGridLineStyleAttrib(Ihandle* ih) { return iMglPlotGetLineStyle(ih->data->gridLineStyle); } static int iMglPlotSetGridAttrib(Ihandle* ih, const char* value) { if (iupStrEqualNoCase(value, "VERTICAL") || iupStrEqualNoCase(value, "X")) ih->data->gridShow = "X"; else if (iupStrEqualNoCase(value, "HORIZONTAL") || iupStrEqualNoCase(value, "Y")) ih->data->gridShow = "Y"; else if (iupStrEqualNoCase(value, "Z")) ih->data->gridShow = "Z"; else if (iupStrEqualNoCase(value, "XY")) ih->data->gridShow = "XY"; else if (iupStrEqualNoCase(value, "XZ")) ih->data->gridShow = "XZ"; else if (iupStrEqualNoCase(value, "YZ")) ih->data->gridShow = "YZ"; else if (iupStrEqualNoCase(value, "YES") || iupStrEqualNoCase(value, "XYZ")) ih->data->gridShow = "XYZ"; else ih->data->gridShow = NULL; ih->data->redraw = true; return 0; } static char* iMglPlotGetGridAttrib(Ihandle* ih) { if (ih->data->gridShow) return ih->data->gridShow; else return "NO"; } static char* iMglPlotGetCountAttrib(Ihandle* ih) { return iupStrReturnInt(ih->data->dataSetCount); } static int iMglPlotSetCurrentAttrib(Ihandle* ih, const char* value) { int ii; ih->data->dataSetCurrent = -1; if (iupStrToInt(value, &ii)) { if (ii>=0 && iidata->dataSetCount) { ih->data->dataSetCurrent = ii; ih->data->redraw = true; } } return 0; } static char* iMglPlotGetCurrentAttrib(Ihandle* ih) { return iupStrReturnInt(ih->data->dataSetCurrent); } static void iMglPlotRemoveDataSet(IdataSet* ds) { free(ds->dsLegend); free(ds->dsMode); if (ds->dsNames) { int j; char** dsNames = (char**)iupArrayGetData(ds->dsNames); int count = iupArrayCount(ds->dsNames); for (j=0; jdsNames); } if (ds->dsX) delete ds->dsX; if (ds->dsY) delete ds->dsY; if (ds->dsZ) delete ds->dsZ; memset(ds, 0, sizeof(IdataSet)); } static int iMglPlotSetRemoveAttrib(Ihandle* ih, const char* value) { int ii; if (iupStrToInt(value, &ii)) { int i; if(ii > ih->data->dataSetCount || ii < 0) return 0; iMglPlotRemoveDataSet(&ih->data->dataSet[ii]); for(i = ii; i < ih->data->dataSetCount-1; i++) ih->data->dataSet[i] = ih->data->dataSet[i+1]; memset(&ih->data->dataSet[ih->data->dataSetCount-1], 0, sizeof(IdataSet)); ih->data->dataSetCount--; if (ih->data->dataSetCurrent > ih->data->dataSetCount-1) ih->data->dataSetCurrent = ih->data->dataSetCount-1; ih->data->redraw = true; } return 0; } static int iMglPlotSetClearAttrib(Ihandle* ih, const char* value) { int i; for(i = 0; i < ih->data->dataSetCount; i++) iMglPlotRemoveDataSet(&ih->data->dataSet[i]); ih->data->dataSetCount = 0; ih->data->dataSetCurrent = -1; ih->data->redraw = true; (void)value; return 0; } static int iMglPlotSetDSRearrangeAttrib(Ihandle* ih, const char* value) { int i; IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; // Must be Planar data if (ds->dsY || ds->dsZ || ds->dsX->nz != 1) return 0; if (ds->dsX->ny == 1) return 0; // Now nx!=1 and ny!=1, so rearrange data from ds->dsX to ds->dsY if (ds->dsX->ny == 2 || ds->dsX->ny == 3) { ds->dsCount = ds->dsX->nx; ds->dsDim = 2; ds->dsY = new mglData(ds->dsCount); mglData* dsX = new mglData(ds->dsCount); double* ax = ds->dsX->a; double* ay = ax + ds->dsCount; double* az = NULL; double* x = dsX->a; double* y = ds->dsY->a; double* z = NULL; if (ds->dsX->ny == 3) { ds->dsZ = new mglData(ds->dsCount); z = ds->dsZ->a; az = ay + ds->dsCount; ds->dsDim = 3; } memcpy(x, ax, ds->dsCount*sizeof(double)); memcpy(y, ay, ds->dsCount*sizeof(double)); if (z) memcpy(z, az, ds->dsCount*sizeof(double)); delete ds->dsX; ds->dsX = dsX; } else if (ds->dsX->nx == 2 || ds->dsX->nx == 3) { ds->dsCount = ds->dsX->ny; ds->dsDim = 2; ds->dsY = new mglData(ds->dsCount); mglData* dsX = new mglData(ds->dsCount); double* a = ds->dsX->a; double* x = dsX->a; double* y = ds->dsY->a; double* z = NULL; if (ds->dsX->nx == 3) { ds->dsZ = new mglData(ds->dsCount); z = ds->dsZ->a; ds->dsDim = 3; } for (i=0; idsCount; i++) { *x++ = *a++; *y++ = *a++; if (z) *z++ = *a++; } delete ds->dsX; ds->dsX = dsX; } else if (ds->dsX->nx == 1) { ds->dsCount = ds->dsX->ny; ds->dsX->nx = ds->dsCount; ds->dsX->ny = 1; } (void)value; return 0; } static int iMglPlotSetDSSplitAttrib(Ihandle* ih, const char* value) { int old_current; IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; // Must be Planar data if (ds->dsY || ds->dsZ || ds->dsX->nz != 1) return 0; if (ds->dsX->ny == 1) return 0; old_current = ih->data->dataSetCurrent; // Now nx!=1 and ny!=1, so rearrange data from ds->dsX to ds->dsY if (ds->dsX->ny == 2 || ds->dsX->ny == 3) { ds->dsCount = ds->dsX->nx; double* ax = ds->dsX->a; double* ay = ax + ds->dsCount; int dsy = IupMglPlotNewDataSet(ih, 1); IupMglPlotSet1D(ih, dsy, NULL, ay, ds->dsCount); if (ds->dsX->ny == 3) { double* az = ay + ds->dsCount; int dsz = IupMglPlotNewDataSet(ih, 1); IupMglPlotSet1D(ih, dsz, NULL, az, ds->dsCount); } ds->dsDim = 1; ds->dsX->ny = 1; } ih->data->dataSetCurrent = old_current; (void)value; return 0; } static int iMglPlotSetDSLineStyleAttrib(Ihandle* ih, const char* value) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetLineStyle(ih, value, ds->dsLineStyle); } static char* iMglPlotGetDSLineStyleAttrib(Ihandle* ih) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return NULL; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotGetLineStyle(ds->dsLineStyle); } static int iMglPlotSetDSLineWidthAttrib(Ihandle* ih, const char* value) { if (ih->data->dataSetCurrent==-1) return 0; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetInt(ih, value, ds->dsLineWidth); } static char* iMglPlotGetDSLineWidthAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return 0; else { IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iupStrReturnInt(ds->dsLineWidth); } } static int iMglPlotSetMarkStyle(Ihandle* ih, const char* value, char& markstyle) { char old_markstyle = markstyle; if (!value || iupStrEqualNoCase(value, "X")) markstyle = 'x'; else if (iupStrEqualNoCase(value, "STAR")) markstyle = '*'; else if (iupStrEqualNoCase(value, "CIRCLE")) markstyle = 'O'; // In fact "#o", we will fix it later in iMglPlotAddStyleMark else if (iupStrEqualNoCase(value, "PLUS")) markstyle = '+'; else if (iupStrEqualNoCase(value, "BOX")) markstyle = 'S'; // In fact "#s", we will fix it later else if (iupStrEqualNoCase(value, "DIAMOND")) markstyle = 'D'; // In fact "#d", we will fix it later else if (iupStrEqualNoCase(value, "HOLLOW_CIRCLE")) markstyle = 'o'; else if (iupStrEqualNoCase(value, "HOLLOW_BOX")) markstyle = 's'; else if (iupStrEqualNoCase(value, "HOLLOW_DIAMOND")) markstyle = 'd'; else if (iupStrEqualNoCase(value, "DOT")) markstyle = '.'; else if (iupStrEqualNoCase(value, "ARROW_UP")) markstyle = '^'; // In fact "#^", we will fix it later else if (iupStrEqualNoCase(value, "ARROW_DOWN")) markstyle = 'V'; // In fact "#V", we will fix it later else if (iupStrEqualNoCase(value, "ARROW_LEFT")) markstyle = '<'; // In fact "#<", we will fix it later else if (iupStrEqualNoCase(value, "ARROW_RIGHT")) markstyle = '>'; // In fact "#>", we will fix it later else markstyle = 'x'; /* reset to default */ if (old_markstyle != markstyle) ih->data->redraw = true; return 0; } static int iMglPlotSetDSMarkStyleAttrib(Ihandle* ih, const char* value) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetMarkStyle(ih, value, ds->dsMarkStyle); } static char* iMglPlotGetDSMarkStyleAttrib(Ihandle* ih) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return NULL; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; switch(ds->dsMarkStyle) { case '*': return "STAR"; case 'O': return "CIRCLE"; case 'x': return "X"; case 'S': return "BOX"; case 'D': return "DIAMOND"; case 'o': return "HOLLOW_CIRCLE"; case 's': return "HOLLOW_BOX"; case 'd': return "HOLLOW_DIAMOND"; case '^': return "ARROW_UP"; case 'V': return "ARROW_DOWN"; case '<': return "ARROW_LEFT"; case '>': return "ARROW_RIGHT"; case '.': return "DOT"; default: return "PLUS"; } } static int iMglPlotSetDSMarkSizeAttrib(Ihandle* ih, const char* value) { if (ih->data->dataSetCurrent==-1) return 0; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetDouble(ih, value, ds->dsMarkSize, 1.0); } static char* iMglPlotGetDSMarkSizeAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; else { IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iupStrReturnDouble(ds->dsMarkSize); } } static int iMglPlotSetDSColorAttrib(Ihandle* ih, const char* value) { if (ih->data->dataSetCurrent==-1) return 0; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; iMglPlotSetColor(ih, value, ds->dsColor); if (mgl_isnan(ds->dsColor.r) || mgl_isnan(ds->dsColor.g) || mgl_isnan(ds->dsColor.b)) iMglPlotSetDsColorDefault(ds->dsColor, ih->data->dataSetCurrent); return 0; } static char* iMglPlotGetDSColorAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotReturnColor(ds->dsColor); } static int iMglPlotSetDSModeAttrib(Ihandle* ih, const char* value) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; free(ds->dsMode); if (value) ds->dsMode = iupStrDup(value); else ds->dsMode = iupStrDup("LINE"); ih->data->redraw = true; return 0; } static char* iMglPlotGetDSModeAttrib(Ihandle* ih) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return NULL; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return ds->dsMode; } static int iMglPlotSetDSLegendAttrib(Ihandle* ih, const char* value) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; free(ds->dsLegend); if (value) ds->dsLegend = iupStrDup(value); else ds->dsLegend = iMglPlotDefaultLegend(ih->data->dataSetCurrent); ih->data->redraw = true; return 0; } static char* iMglPlotGetDSLegendAttrib(Ihandle* ih) { IdataSet* ds; if (ih->data->dataSetCurrent==-1) return NULL; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return ds->dsLegend; } static int iMglPlotSetDSShowValuesAttrib(Ihandle* ih, const char* value) { if (ih->data->dataSetCurrent==-1) return 0; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetBoolean(ih, value, ds->dsShowValues); } static char* iMglPlotGetDSShowValuesAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iupStrReturnBoolean(ds->dsShowValues); } static int iMglPlotSetDSShowMarksAttrib(Ihandle* ih, const char* value) { if (ih->data->dataSetCurrent==-1) return 0; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iMglPlotSetBoolean(ih, value, ds->dsShowMarks); } static char* iMglPlotGetDSShowMarksAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iupStrReturnBoolean(ds->dsShowMarks); } static int iMglPlotSetDSRemoveAttrib(Ihandle* ih, const char* value) { IdataSet* ds; int index, remove_count=1; if (ih->data->dataSetCurrent==-1) return 0; ds = &ih->data->dataSet[ih->data->dataSetCurrent]; if (iMglPlotIsPlanarOrVolumetricData(ds)) return 0; if (iupStrToIntInt(value, &index, &remove_count, ':')) { if(index < 0 || index+remove_count > ds->dsCount) return 0; if (index+remove_count < ds->dsCount) /* if equal, remove at the end, no need to move data */ { memmove(ds->dsX->a + index, ds->dsX->a + (index + remove_count), sizeof(double)*(ds->dsCount - (index + remove_count))); if (ds->dsY) memmove(ds->dsY->a + index, ds->dsY->a + (index + remove_count), sizeof(double)*(ds->dsCount - (index + remove_count))); if (ds->dsZ) memmove(ds->dsZ->a + index, ds->dsZ->a + (index + remove_count), sizeof(double)*(ds->dsCount - (index + remove_count))); } ds->dsX->Crop(ds->dsCount, 1, 'x'); if (ds->dsY) ds->dsY->Crop(ds->dsCount, 1, 'y'); if (ds->dsZ) ds->dsZ->Crop(ds->dsCount, 1, 'z'); ds->dsCount -= remove_count; if (ds->dsNames) { char** dsNames = (char**)iupArrayGetData(ds->dsNames); free(dsNames[index]); iupArrayRemove(ds->dsNames, index, remove_count); } ih->data->redraw = true; } return 0; } static char* iMglPlotGetDSCountAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; else { IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; return iupStrReturnInt(ds->dsCount); } } static char* iMglPlotGetDSDimAttrib(Ihandle* ih) { if (ih->data->dataSetCurrent==-1) return NULL; else { IdataSet* ds = &ih->data->dataSet[ih->data->dataSetCurrent]; if (iMglPlotIsPlanarOrVolumetricData(ds)) return iupStrReturnStrf("%dx%dx%d", (int)ds->dsX->nx, (int)ds->dsX->ny, (int)ds->dsX->nz); else return iupStrReturnInt(ds->dsDim); } } static int iMglPlotSetBoxAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->Box); } static char* iMglPlotGetBoxAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->Box); } static int iMglPlotSetBoxTicksAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->boxTicks); } static char* iMglPlotGetBoxTicksAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->boxTicks); } static int iMglPlotSetAxisLabelPosition(Ihandle* ih, const char* value, int& pos) { int old_pos = pos; if (iupStrEqualNoCase(value, "CENTER")) pos = 0; else if (iupStrEqualNoCase(value, "MIN")) pos = -1; else if (iupStrEqualNoCase(value, "MAX")) pos = 1; if (old_pos != pos) ih->data->redraw = true; return 0; } static char* iMglPlotGetAxisLabelPosition(int pos) { if (pos == 0) return "CENTER"; if (pos == 1) return "MAX"; if (pos == -1) return "MIN"; return NULL; } static int iMglPlotSetAxisXLabelPositionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisLabelPosition(ih, value, ih->data->axisX.axLabelPos); } static int iMglPlotSetAxisYLabelPositionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisLabelPosition(ih, value, ih->data->axisY.axLabelPos); } static int iMglPlotSetAxisZLabelPositionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisLabelPosition(ih, value, ih->data->axisZ.axLabelPos); } static char* iMglPlotGetAxisXLabelPositionAttrib(Ihandle* ih) { return iMglPlotGetAxisLabelPosition(ih->data->axisX.axLabelPos); } static char* iMglPlotGetAxisYLabelPositionAttrib(Ihandle* ih) { return iMglPlotGetAxisLabelPosition(ih->data->axisY.axLabelPos); } static char* iMglPlotGetAxisZLabelPositionAttrib(Ihandle* ih) { return iMglPlotGetAxisLabelPosition(ih->data->axisZ.axLabelPos); } static int iMglPlotSetAxisXLabelRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axLabelRotation); } static int iMglPlotSetAxisYLabelRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axLabelRotation); } static int iMglPlotSetAxisZLabelRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axLabelRotation); } static char* iMglPlotGetAxisXLabelRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axLabelRotation); } static char* iMglPlotGetAxisYLabelRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axLabelRotation); } static char* iMglPlotGetAxisZLabelRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axLabelRotation); } static int iMglPlotSetAxisXLabelCenteredAttrib(Ihandle* ih, const char* value) { if (iupStrBoolean(value)) return iMglPlotSetAxisLabelPosition(ih, "CENTER", ih->data->axisX.axLabelPos); else return iMglPlotSetAxisLabelPosition(ih, "MAX", ih->data->axisX.axLabelPos); } static int iMglPlotSetAxisYLabelCenteredAttrib(Ihandle* ih, const char* value) { if (iupStrBoolean(value)) return iMglPlotSetAxisLabelPosition(ih, "CENTER", ih->data->axisY.axLabelPos); else return iMglPlotSetAxisLabelPosition(ih, "MAX", ih->data->axisY.axLabelPos); } static int iMglPlotSetAxisZLabelCenteredAttrib(Ihandle* ih, const char* value) { if (iupStrBoolean(value)) return iMglPlotSetAxisLabelPosition(ih, "CENTER", ih->data->axisZ.axLabelPos); else return iMglPlotSetAxisLabelPosition(ih, "MAX", ih->data->axisZ.axLabelPos); } static char* iMglPlotGetAxisXLabelCenteredAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axLabelPos==0? true: false); } static char* iMglPlotGetAxisYLabelCenteredAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axLabelPos==0? true: false); } static char* iMglPlotGetAxisZLabelCenteredAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axLabelPos==0? true: false); } static int iMglPlotSetAxisXColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->axisX.axColor); } static int iMglPlotSetAxisYColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->axisY.axColor); } static int iMglPlotSetAxisZColorAttrib(Ihandle* ih, const char* value) { return iMglPlotSetColor(ih, value, ih->data->axisZ.axColor); } static char* iMglPlotGetAxisXColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->axisX.axColor); } static char* iMglPlotGetAxisYColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->axisY.axColor); } static char* iMglPlotGetAxisZColorAttrib(Ihandle* ih) { return iMglPlotReturnColor(ih->data->axisZ.axColor); } static int iMglPlotSetAxisXFontSizeAttrib(Ihandle* ih, const char* value) { if (!value) { ih->data->alpha = 0.5; ih->data->redraw = true; return 0; } else return iMglPlotSetDouble(ih, value, ih->data->axisX.axLabelFontSizeFactor, 0.8); } static int iMglPlotSetAxisYFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisY.axLabelFontSizeFactor, 0.8); } static int iMglPlotSetAxisZFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisZ.axLabelFontSizeFactor, 0.8); } static char* iMglPlotGetAxisXFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axLabelFontSizeFactor); } static char* iMglPlotGetAxisYFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axLabelFontSizeFactor); } static char* iMglPlotGetAxisZFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axLabelFontSizeFactor); } static int iMglPlotSetAxisXFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisX.axLabelFontStyle); } static int iMglPlotSetAxisYFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisY.axLabelFontStyle); } static int iMglPlotSetAxisZFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisZ.axLabelFontStyle); } static char* iMglPlotGetAxisXFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisX.axLabelFontStyle); } static char* iMglPlotGetAxisYFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisY.axLabelFontStyle); } static char* iMglPlotGetAxisZFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisZ.axLabelFontStyle); } static int iMglPlotSetAxisXTickFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisX.axTickFontSizeFactor, 0.8); } static int iMglPlotSetAxisYTickFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisY.axTickFontSizeFactor, 0.8); } static int iMglPlotSetAxisZTickFontSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisZ.axTickFontSizeFactor, 0.8); } static char* iMglPlotGetAxisXTickFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axTickFontSizeFactor); } static char* iMglPlotGetAxisYTickFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axTickFontSizeFactor); } static char* iMglPlotGetAxisZTickFontSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axTickFontSizeFactor); } static int iMglPlotSetAxisXTickFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisX.axTickFontStyle); } static int iMglPlotSetAxisYTickFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisY.axTickFontStyle); } static int iMglPlotSetAxisZTickFontStyleAttrib(Ihandle* ih, const char* value) { return iMglPlotSetFontStyle(ih, value, ih->data->axisZ.axTickFontStyle); } static char* iMglPlotGetAxisXTickFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisX.axTickFontStyle); } static char* iMglPlotGetAxisYTickFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisY.axTickFontStyle); } static char* iMglPlotGetAxisZTickFontStyleAttrib(Ihandle* ih) { return iMglPlotGetFontStyle(ih->data->axisZ.axTickFontStyle); } static int iMglPlotSetAxisXTickMinorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisX.axTickMinorSizeFactor, 1.0); } static int iMglPlotSetAxisYTickMinorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisY.axTickMinorSizeFactor, 1.0); } static int iMglPlotSetAxisZTickMinorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisZ.axTickMinorSizeFactor, 1.0); } static char* iMglPlotGetAxisXTickMinorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axTickMinorSizeFactor); } static char* iMglPlotGetAxisYTickMinorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axTickMinorSizeFactor); } static char* iMglPlotGetAxisZTickMinorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axTickMinorSizeFactor); } static int iMglPlotSetAxisXTickMajorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisX.axTickMajorSize, 0.02); } static int iMglPlotSetAxisYTickMajorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisY.axTickMajorSize, 0.02); } static int iMglPlotSetAxisZTickMajorSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisZ.axTickMajorSize, 0.02); } static char* iMglPlotGetAxisXTickMajorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axTickMajorSize); } static char* iMglPlotGetAxisYTickMajorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axTickMajorSize); } static char* iMglPlotGetAxisZTickMajorSizeAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axTickMajorSize); } static int iMglPlotSetAxisXTickMajorSpanAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisX.axTickMajorSpan, -5.0); } static int iMglPlotSetAxisYTickMajorSpanAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisY.axTickMajorSpan, -5.0); } static int iMglPlotSetAxisZTickMajorSpanAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->axisZ.axTickMajorSpan, -5.0); } static char* iMglPlotGetAxisXTickMajorSpanAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axTickMajorSpan); } static char* iMglPlotGetAxisYTickMajorSpanAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axTickMajorSpan); } static char* iMglPlotGetAxisZTickMajorSpanAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axTickMajorSpan); } static char* iMglPlotSetAxisScale(Ihandle* ih, const char* value, char dir) { const char* scale; if (!value || iupStrEqualNoCase(value, "LIN")) scale = NULL; else if(iupStrEqualNoCase(value, "LOG10")) scale = (dir=='x')? "lg(x)": (dir=='y'? "lg(y)": "lg(z)"); else if(iupStrEqualNoCase(value, "LOG2")) scale = (dir=='x')? "log(x, 2)": (dir=='y'? "log(y, 2)": "log(z, 2)"); else if(iupStrEqualNoCase(value, "LOGN")) scale = (dir=='x')? "ln(x)": (dir=='y'? "ln(y)": "ln(z)"); else scale = NULL; ih->data->redraw = true; return (char*)scale; } static int iMglPlotSetAxisXScaleAttrib(Ihandle* ih, const char* value) { ih->data->axisX.axScale = iMglPlotSetAxisScale(ih, value, 'x'); return 0; } static int iMglPlotSetAxisYScaleAttrib(Ihandle* ih, const char* value) { ih->data->axisY.axScale = iMglPlotSetAxisScale(ih, value, 'y'); return 0; } static int iMglPlotSetAxisZScaleAttrib(Ihandle* ih, const char* value) { ih->data->axisZ.axScale = iMglPlotSetAxisScale(ih, value, 'z'); return 0; } static char* iMglPlotGetAxisScale(const char* scale) { if (!scale) return "LIN"; else if (strstr(scale, "lg")) return "LOG10"; else if (strstr(scale, "log")) return "LOG2"; else if (strstr(scale, "ln")) return "LOGN"; return NULL; } static char* iMglPlotGetAxisXScaleAttrib(Ihandle* ih) { return iMglPlotGetAxisScale(ih->data->axisX.axScale); } static char* iMglPlotGetAxisYScaleAttrib(Ihandle* ih) { return iMglPlotGetAxisScale(ih->data->axisY.axScale); } static char* iMglPlotGetAxisZScaleAttrib(Ihandle* ih) { return iMglPlotGetAxisScale(ih->data->axisZ.axScale); } static int iMglPlotSetAxisXReverseAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axReverse); } static int iMglPlotSetAxisYReverseAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axReverse); } static int iMglPlotSetAxisZReverseAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axReverse); } static char* iMglPlotGetAxisXReverseAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axReverse); } static char* iMglPlotGetAxisYReverseAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axReverse); } static char* iMglPlotGetAxisZReverseAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axReverse); } static int iMglPlotSetAxisXShowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axShow); } static int iMglPlotSetAxisYShowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axShow); } static int iMglPlotSetAxisZShowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axShow); } static char* iMglPlotGetAxisXShowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axShow); } static char* iMglPlotGetAxisYShowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axShow); } static char* iMglPlotGetAxisZShowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axShow); } static int iMglPlotSetAxisXShowArrowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axShowArrow); } static int iMglPlotSetAxisYShowArrowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axShowArrow); } static int iMglPlotSetAxisZShowArrowAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axShowArrow); } static char* iMglPlotGetAxisXShowArrowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axShowArrow); } static char* iMglPlotGetAxisYShowArrowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axShowArrow); } static char* iMglPlotGetAxisZShowArrowAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axShowArrow); } static int iMglPlotSetAxisXTickShowValuesAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axTickShowValues); } static int iMglPlotSetAxisYTickShowValuesAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axTickShowValues); } static int iMglPlotSetAxisZTickShowValuesAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axTickShowValues); } static char* iMglPlotGetAxisXTickShowValuesAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axTickShowValues); } static char* iMglPlotGetAxisYTickShowValuesAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axTickShowValues); } static char* iMglPlotGetAxisZTickShowValuesAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axTickShowValues); } static int iMglPlotSetAxisXTickAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axTickShow); } static int iMglPlotSetAxisYTickAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axTickShow); } static int iMglPlotSetAxisZTickAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axTickShow); } static char* iMglPlotGetAxisXTickAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axTickShow); } static char* iMglPlotGetAxisYTickAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axTickShow); } static char* iMglPlotGetAxisZTickAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axTickShow); } static int iMglPlotSetAxisXTickAutoSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axTickAutoSize); } static int iMglPlotSetAxisYTickAutoSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axTickAutoSize); } static int iMglPlotSetAxisZTickAutoSizeAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axTickAutoSize); } static char* iMglPlotGetAxisXTickAutoSizeAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axTickAutoSize); } static char* iMglPlotGetAxisYTickAutoSizeAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axTickAutoSize); } static char* iMglPlotGetAxisZTickAutoSizeAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axTickAutoSize); } static int iMglPlotSetAxisXTickAutoAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axTickAutoSpace); } static int iMglPlotSetAxisYTickAutoAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axTickAutoSpace); } static int iMglPlotSetAxisZTickAutoAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axTickAutoSpace); } static char* iMglPlotGetAxisXTickAutoAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axTickAutoSpace); } static char* iMglPlotGetAxisYTickAutoAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axTickAutoSpace); } static char* iMglPlotGetAxisZTickAutoAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axTickAutoSpace); } static int iMglPlotSetAxisXTickValuesRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axTickValuesRotation); } static int iMglPlotSetAxisYTickValuesRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axTickValuesRotation); } static int iMglPlotSetAxisZTickValuesRotationAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axTickValuesRotation); } static char* iMglPlotGetAxisXTickValuesRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axTickValuesRotation); } static char* iMglPlotGetAxisYTickValuesRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axTickValuesRotation); } static char* iMglPlotGetAxisZTickValuesRotationAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axTickValuesRotation); } static int iMglPlotSetAxisXTickMinorDivisionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetInt(ih, value, ih->data->axisX.axTickMinorDivision); } static int iMglPlotSetAxisYTickMinorDivisionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetInt(ih, value, ih->data->axisY.axTickMinorDivision); } static int iMglPlotSetAxisZTickMinorDivisionAttrib(Ihandle* ih, const char* value) { return iMglPlotSetInt(ih, value, ih->data->axisZ.axTickMinorDivision); } static char* iMglPlotGetAxisXTickMinorDivisionAttrib(Ihandle* ih) { return iupStrReturnInt(ih->data->axisX.axTickMinorDivision); } static char* iMglPlotGetAxisYTickMinorDivisionAttrib(Ihandle* ih) { return iupStrReturnInt(ih->data->axisY.axTickMinorDivision); } static char* iMglPlotGetAxisZTickMinorDivisionAttrib(Ihandle* ih) { return iupStrReturnInt(ih->data->axisZ.axTickMinorDivision); } static int iMglPlotSetAxisXAutoMinAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axAutoScaleMin); } static int iMglPlotSetAxisYAutoMinAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axAutoScaleMin); } static int iMglPlotSetAxisZAutoMinAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axAutoScaleMin); } static char* iMglPlotGetAxisXAutoMinAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axAutoScaleMin); } static char* iMglPlotGetAxisYAutoMinAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axAutoScaleMin); } static char* iMglPlotGetAxisZAutoMinAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axAutoScaleMin); } static int iMglPlotSetAxisXAutoMaxAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisX.axAutoScaleMax); } static int iMglPlotSetAxisYAutoMaxAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisY.axAutoScaleMax); } static int iMglPlotSetAxisZAutoMaxAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->axisZ.axAutoScaleMax); } static char* iMglPlotGetAxisXAutoMaxAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisX.axAutoScaleMax); } static char* iMglPlotGetAxisYAutoMaxAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisY.axAutoScaleMax); } static char* iMglPlotGetAxisZAutoMaxAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->axisZ.axAutoScaleMax); } static int iMglPlotSetAxisXMinAttrib(Ihandle* ih, const char* value) { ih->data->axisX.axAutoScaleMin = false; return iMglPlotSetDouble(ih, value, ih->data->axisX.axMin, -1.0); } static int iMglPlotSetAxisYMinAttrib(Ihandle* ih, const char* value) { ih->data->axisY.axAutoScaleMin = false; return iMglPlotSetDouble(ih, value, ih->data->axisY.axMin, -1.0); } static int iMglPlotSetAxisZMinAttrib(Ihandle* ih, const char* value) { ih->data->axisZ.axAutoScaleMin = false; return iMglPlotSetDouble(ih, value, ih->data->axisZ.axMin, -1.0); } static char* iMglPlotGetAxisXMinAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axMin); } static char* iMglPlotGetAxisYMinAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axMin); } static char* iMglPlotGetAxisZMinAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axMin); } static int iMglPlotSetAxisXMaxAttrib(Ihandle* ih, const char* value) { ih->data->axisX.axAutoScaleMax = false; return iMglPlotSetDouble(ih, value, ih->data->axisX.axMax, 1.0); } static int iMglPlotSetAxisYMaxAttrib(Ihandle* ih, const char* value) { ih->data->axisY.axAutoScaleMax = false; return iMglPlotSetDouble(ih, value, ih->data->axisY.axMax, 1.0); } static int iMglPlotSetAxisZMaxAttrib(Ihandle* ih, const char* value) { ih->data->axisZ.axAutoScaleMax = false; return iMglPlotSetDouble(ih, value, ih->data->axisZ.axMax, 1.0); } static char* iMglPlotGetAxisXMaxAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisX.axMax); } static char* iMglPlotGetAxisYMaxAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisY.axMax); } static char* iMglPlotGetAxisZMaxAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->axisZ.axMax); } static int iMglPlotSetAxisCrossOrigin(Ihandle* ih, const char* value, double& origin) { double old_origin = origin; if (iupStrBoolean(value)) origin = 0; else origin = NAN; if (old_origin != origin) ih->data->redraw = true; return 0; } static int iMglPlotSetAxisXCrossOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisCrossOrigin(ih, value, ih->data->axisX.axOrigin); } static int iMglPlotSetAxisYCrossOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisCrossOrigin(ih, value, ih->data->axisY.axOrigin); } static int iMglPlotSetAxisZCrossOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisCrossOrigin(ih, value, ih->data->axisZ.axOrigin); } static char* iMglPlotGetAxisXCrossOrigin(double origin) { if (origin==0) return "YES"; else if (mgl_isnan(origin)) return "NO"; else return NULL; } static char* iMglPlotGetAxisXCrossOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisXCrossOrigin(ih->data->axisX.axOrigin); } static char* iMglPlotGetAxisYCrossOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisXCrossOrigin(ih->data->axisY.axOrigin); } static char* iMglPlotGetAxisZCrossOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisXCrossOrigin(ih->data->axisZ.axOrigin); } static int iMglPlotSetAxisOrigin(Ihandle* ih, const char* value, double& num) { double old_num = num; if (!value) num = NAN; else iupStrToDouble(value, &num); if (old_num != num) ih->data->redraw = true; return 0; } static int iMglPlotSetAxisXOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisOrigin(ih, value, ih->data->axisX.axOrigin); } static int iMglPlotSetAxisYOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisOrigin(ih, value, ih->data->axisY.axOrigin); } static int iMglPlotSetAxisZOriginAttrib(Ihandle* ih, const char* value) { return iMglPlotSetAxisOrigin(ih, value, ih->data->axisZ.axOrigin); } static char* iMglPlotGetAxisOrigin(double Origin) { if (!mgl_isnan(Origin)) return iupStrReturnDouble(Origin); else return NULL; } static char* iMglPlotGetAxisXOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisOrigin(ih->data->axisX.axOrigin); } static char* iMglPlotGetAxisYOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisOrigin(ih->data->axisY.axOrigin); } static char* iMglPlotGetAxisZOriginAttrib(Ihandle* ih) { return iMglPlotGetAxisOrigin(ih->data->axisZ.axOrigin); } static int iMglPlotSetAlphaAttrib(Ihandle* ih, const char* value) { return iMglPlotSetDouble(ih, value, ih->data->alpha, 0.5); } static char* iMglPlotGetAlphaAttrib(Ihandle* ih) { return iupStrReturnDouble(ih->data->alpha); } static int iMglPlotSetTransparentAttrib(Ihandle* ih, const char* value) { return iMglPlotSetBoolean(ih, value, ih->data->transparent); } static char* iMglPlotGetTransparentAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->transparent); } static void iMglPlotInitOpenGL2D(Ihandle* ih) { IupGLMakeCurrent(ih); glViewport(0, 0, ih->data->w, ih->data->h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (!ih->data->opengl) { glTranslatef(-1.0, 0, 0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); /* data alignment is 1 */ glPixelZoom(1.0, -1.0); // vertical flip image glRasterPos2f(0, 1.0); } } static int iMglPlotSetOpenGLAttrib(Ihandle* ih, const char* value) { bool old_opengl = ih->data->opengl; iMglPlotSetBoolean(ih, value, ih->data->opengl); if (old_opengl != ih->data->opengl) { // No need to reset attrib since mgl will be used only in ACTION delete ih->data->mgl; ih->data->redraw = 1; if (ih->handle) iMglPlotInitOpenGL2D(ih); ih->data->mgl = new mglGraph(ih->data->opengl, ih->data->w, ih->data->h); } return 0; } static char* iMglPlotGetOpenGLAttrib(Ihandle* ih) { return iupStrReturnBoolean(ih->data->opengl); } static int iMglPlotSetAntialiasAttrib(Ihandle* ih, const char* value) { if (!ih->data->opengl) return 0; IupGLMakeCurrent(ih); if (iupStrBoolean(value)) { glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); } else { glDisable(GL_POINT_SMOOTH); glDisable(GL_LINE_SMOOTH); glDisable(GL_POLYGON_SMOOTH); } return 0; } static char* iMglPlotGetAntialiasAttrib(Ihandle* ih) { if (!ih->data->opengl) return NULL; IupGLMakeCurrent(ih); return iupStrReturnBoolean(glIsEnabled(GL_LINE_SMOOTH)==GL_TRUE); } static char* iMglPlotGetMglGraphAttrib(Ihandle* ih) { return (char*)ih->data->mgl; } static int iMglPlotSetZoomAttrib(Ihandle* ih, const char* value) { if (!value) { ih->data->x1 = 0; ih->data->y1 = 0; ih->data->x2 = 1.0; ih->data->y2 = 1.0; } else { sscanf(value, "%lf:%lf:%lf:%lf", &(ih->data->x1), &(ih->data->y1), &(ih->data->x2), &(ih->data->y2)); if (ih->data->x1 < 0) ih->data->x1 = 0; if (ih->data->y1 < 0) ih->data->y1 = 0; if (ih->data->x2 > 1.0) ih->data->x2 = 1.0; if (ih->data->y2 > 1.0) ih->data->y2 = 1.0; } ih->data->redraw = true; return 0; } static char* iMglPlotGetZoomAttrib(Ihandle* ih) { return iupStrReturnStrf(IUP_DOUBLE2STR ":" IUP_DOUBLE2STR ":" IUP_DOUBLE2STR ":" IUP_DOUBLE2STR, ih->data->x1, ih->data->y1, ih->data->x2, ih->data->y2); } static int iMglPlotSetRotateAttrib(Ihandle* ih, const char* value) { if (!value) { ih->data->rotX = 0; ih->data->rotY = 0; ih->data->rotZ = 0; } else sscanf(value, "%lf:%lf:%lf", &(ih->data->rotX), &(ih->data->rotY), &(ih->data->rotZ)); ih->data->redraw = true; return 0; } static char* iMglPlotGetRotateAttrib(Ihandle* ih) { return iupStrReturnStrf(IUP_DOUBLE2STR ":" IUP_DOUBLE2STR ":" IUP_DOUBLE2STR, ih->data->rotX, ih->data->rotY, ih->data->rotZ); } static char* iMglPlotGetErrorMessageAttrib(Ihandle* ih) { char* err = (char*)ih->data->mgl->Message(); if (err && err[0] != 0) return err; else return NULL; } static int iMglPlotSetSuppressWarningAttrib(Ihandle*, const char* value) { if (iupStrBoolean(value)) mglGraph::SuppressWarn(true); else mglGraph::SuppressWarn(false); return 0; } /****************************************************************************** Additional Functions ******************************************************************************/ int IupMglPlotNewDataSet(Ihandle *ih, int dim) { int ds_index; IdataSet* ds; iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return -1; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return -1; /* Increment the number of datasets */ ih->data->dataSetCount++; // Allocate memory if necessary if(ih->data->dataSetCount == ih->data->dataSetMaxCount) { ih->data->dataSetMaxCount += ih->data->dataSetMaxCount; ih->data->dataSet = (IdataSet*)realloc(ih->data->dataSet, ih->data->dataSetMaxCount*sizeof(IdataSet)); memset(ih->data->dataSet+ih->data->dataSetCount-1, 0, sizeof(IdataSet)*(ih->data->dataSetMaxCount - (ih->data->dataSetCount-1))); } ds_index = ih->data->dataSetCount-1; ds = &ih->data->dataSet[ds_index]; ds->dsDim = dim; ds->dsX = new mglData(); if (dim > 1) ds->dsY = new mglData(); if (dim > 2) ds->dsZ = new mglData(); ds->dsCount = 0; /* Initialize the default values */ iMglPlotDataSetDefaults(ih, ds, ds_index); ih->data->redraw = true; ih->data->dataSetCurrent = ds_index; return ih->data->dataSetCurrent; } void IupMglPlotBegin(Ihandle* ih, int dim) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; Iarray* inXData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_XDATA"); Iarray* inYData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_YDATA"); Iarray* inZData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_ZDATA"); Iarray* inNames = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_NAMES"); if (inXData) { iupArrayDestroy(inXData); inXData = NULL;} if (inYData) { iupArrayDestroy(inYData); inYData = NULL;} if (inZData) { iupArrayDestroy(inZData); inZData = NULL;} if (inNames) iupArrayDestroy(inNames); inXData = iupArrayCreate(10, sizeof(double)); if (dim>1) inYData = iupArrayCreate(10, sizeof(double)); if (dim>2) inZData = iupArrayCreate(10, sizeof(double)); iupAttribSet(ih, "_IUP_MGLPLOT_XDATA", (char*)inXData); iupAttribSet(ih, "_IUP_MGLPLOT_YDATA", (char*)inYData); iupAttribSet(ih, "_IUP_MGLPLOT_ZDATA", (char*)inZData); iupAttribSet(ih, "_IUP_MGLPLOT_NAMES", NULL); } int IupMglPlotEnd(Ihandle* ih) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return -1; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return -1; Iarray* inXData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_XDATA"); Iarray* inYData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_YDATA"); Iarray* inZData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_ZDATA"); Iarray* inNames = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_NAMES"); int dim = 0; if (inXData) dim = 1; if (inYData) dim = 2; if (inZData) dim = 3; if (dim == 0) return -1; // Actually add the dataset only at the End int ds_index = IupMglPlotNewDataSet(ih, dim); if (dim==1) { int j; char** names = NULL; if (inNames) names = (char**)iupArrayGetData(inNames); double* x = (double*)iupArrayGetData(inXData); int count = iupArrayCount(inXData); IupMglPlotSet1D(ih, ds_index, (const char**)names, x, count); if (names) { for (j = 0; j < count; j++) free(names[j]); } } else if (dim==2) { double* x = (double*)iupArrayGetData(inXData); double* y = (double*)iupArrayGetData(inYData); int count = iupArrayCount(inXData); IupMglPlotSet2D(ih, ds_index, x, y, count); } else if (dim==3) { double* x = (double*)iupArrayGetData(inXData); double* y = (double*)iupArrayGetData(inYData); double* z = (double*)iupArrayGetData(inZData); int count = iupArrayCount(inXData); IupMglPlotSet3D(ih, ds_index, x, y, z, count); } if (inXData) iupArrayDestroy(inXData); if (inYData) iupArrayDestroy(inYData); if (inZData) iupArrayDestroy(inZData); if (inNames) iupArrayDestroy(inNames); iupAttribSet(ih, "_IUP_MGLPLOT_XDATA", NULL); iupAttribSet(ih, "_IUP_MGLPLOT_YDATA", NULL); iupAttribSet(ih, "_IUP_MGLPLOT_ZDATA", NULL); iupAttribSet(ih, "_IUP_MGLPLOT_NAMES", NULL); return ds_index; } void IupMglPlotAdd1D(Ihandle* ih, const char* inName, double inX) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; Iarray* inXData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_XDATA"); Iarray* inYData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_YDATA"); Iarray* inZData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_ZDATA"); int dim = 0; if (inXData) dim = 1; if (inYData) dim = 2; if (inZData) dim = 3; if (dim < 1) return; int sample_index = iupArrayCount(inXData); /* get before incrementing the array */ if (inName) { Iarray* inNames = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_NAMES"); if (!inNames) { inNames = iupArrayCreate(10, sizeof(char*)); iupAttribSet(ih, "_IUP_MGLPLOT_NAMES", (char*)inNames); } if (inNames) { char** names = (char**)iupArrayInc(inNames); names[sample_index] = iupStrDup(inName); } } double* x = (double*)iupArrayInc(inXData); x[sample_index] = inX; } void IupMglPlotAdd2D(Ihandle* ih, double inX, double inY) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; Iarray* inXData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_XDATA"); Iarray* inYData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_YDATA"); Iarray* inZData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_ZDATA"); int dim = 0; if (inXData) dim = 1; if (inYData) dim = 2; if (inZData) dim = 3; if (dim < 2) return; int sample_index = iupArrayCount(inXData); /* get before incrementing the array */ double* x = (double*)iupArrayInc(inXData); double* y = (double*)iupArrayInc(inYData); x[sample_index] = inX; y[sample_index] = inY; } void IupMglPlotAdd3D(Ihandle *ih, double inX, double inY, double inZ) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; Iarray* inXData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_XDATA"); Iarray* inYData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_YDATA"); Iarray* inZData = (Iarray*)iupAttribGet(ih, "_IUP_MGLPLOT_ZDATA"); int dim = 0; if (inXData) dim = 1; if (inYData) dim = 2; if (inZData) dim = 3; if (dim < 3) return; int sample_index = iupArrayCount(inXData); /* get before incrementing the array */ double* x = (double*)iupArrayInc(inXData); double* y = (double*)iupArrayInc(inYData); double* z = (double*)iupArrayInc(inZData); x[sample_index] = inX; y[sample_index] = inY; z[sample_index] = inZ; } void IupMglPlotInsert1D(Ihandle* ih, int inIndex, int inSampleIndex, const char** inNames, const double* inX, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if(inSampleIndex > ds->dsCount || inSampleIndex < 0) return; ds->dsCount += inCount; ds->dsX->Extend(ds->dsCount); if (inSampleIndex < ds->dsCount-1) // insert in the middle, open space first memmove(ds->dsX->a + inSampleIndex + inCount, ds->dsX->a + inSampleIndex, inCount*sizeof(double)); memcpy(ds->dsX->a + inSampleIndex, inX, inCount*sizeof(double)); if (inNames && ds->dsNames && inIndex==0) // Allow names only for the first dataset { char** dsNames = (char**)iupArrayInsert(ds->dsNames, inSampleIndex, inCount); for (int i = 0; i < inCount; i++) { dsNames[inSampleIndex] = iupStrDup(inNames[i]!=NULL? inNames[i]: ""); inSampleIndex++; } } } void IupMglPlotInsert2D(Ihandle* ih, int inIndex, int inSampleIndex, const double *inX, const double *inY, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (!ds->dsY) return; if(inSampleIndex > ds->dsCount || inSampleIndex < 0) return; ds->dsCount += inCount; ds->dsX->Extend(ds->dsCount); ds->dsY->Extend(ds->dsCount); if (inSampleIndex < ds->dsCount-1) // insert in the middle, open space first { memmove(ds->dsX->a + inSampleIndex + inCount, ds->dsX->a + inSampleIndex, inCount*sizeof(double)); memmove(ds->dsY->a + inSampleIndex + inCount, ds->dsY->a + inSampleIndex, inCount*sizeof(double)); } memcpy(ds->dsX->a + inSampleIndex, inX, inCount*sizeof(double)); memcpy(ds->dsY->a + inSampleIndex, inY, inCount*sizeof(double)); } void IupMglPlotInsert3D(Ihandle* ih, int inIndex, int inSampleIndex, const double* inX, const double* inY, const double* inZ, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (!ds->dsY || !ds->dsZ) return; if(inSampleIndex > ds->dsCount || inSampleIndex < 0) return; ds->dsCount += inCount; ds->dsX->Extend(ds->dsCount); ds->dsY->Extend(ds->dsCount); ds->dsZ->Extend(ds->dsCount); if (inSampleIndex < ds->dsCount-1) // insert in the middle, open space first { memmove(ds->dsX->a + inSampleIndex + inCount, ds->dsX->a + inSampleIndex, inCount*sizeof(double)); memmove(ds->dsY->a + inSampleIndex + inCount, ds->dsY->a + inSampleIndex, inCount*sizeof(double)); memmove(ds->dsZ->a + inSampleIndex + inCount, ds->dsZ->a + inSampleIndex, inCount*sizeof(double)); } memcpy(ds->dsX->a + inSampleIndex, inX, inCount*sizeof(double)); memcpy(ds->dsY->a + inSampleIndex, inY, inCount*sizeof(double)); memcpy(ds->dsZ->a + inSampleIndex, inZ, inCount*sizeof(double)); } void IupMglPlotSet1D(Ihandle* ih, int inIndex, const char** inNames, const double* inX, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (inNames && inIndex==0) // Allow names only for the first dataset { char** dsNames; int j; if (!ds->dsNames) { ds->dsNames = iupArrayCreate(10, sizeof(char*)); dsNames = (char**)iupArrayAdd(ds->dsNames, inCount); } else { dsNames = (char**)iupArrayGetData(ds->dsNames); int count = iupArrayCount(ds->dsNames); for (j=0; jdsNames, inCount - count); else if (count > inCount) iupArrayRemove(ds->dsNames, inCount, count - inCount); } for (j = 0; j < inCount; j++) { dsNames[j] = iupStrDup(inNames[j]!=NULL? inNames[j]: ""); } } ds->dsX->Set(inX, inCount); ds->dsCount = inCount; ih->data->redraw = true; } void IupMglPlotSet2D(Ihandle* ih, int inIndex, const double *inX, const double *inY, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (!ds->dsY) return; ds->dsX->Set(inX, inCount); ds->dsY->Set(inY, inCount); ds->dsCount = inCount; ih->data->redraw = true; } void IupMglPlotSet3D(Ihandle* ih, int inIndex, const double* inX, const double* inY, const double* inZ, int inCount) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || inCount<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (!ds->dsY || !ds->dsZ) return; ds->dsX->Set(inX, inCount); ds->dsY->Set(inY, inCount); ds->dsZ->Set(inZ, inCount); ds->dsCount = inCount; ih->data->redraw = true; } void IupMglPlotSetData(Ihandle* ih, int inIndex, const double* data, int count_x, int count_y, int count_z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || count_x<=0 || count_y<=0 || count_z<=0) return; IdataSet* ds = &ih->data->dataSet[inIndex]; ds->dsX->Set(data, count_x, count_y, count_z); ds->dsCount = count_x*count_y*count_z; ih->data->redraw = true; } void IupMglPlotLoadData(Ihandle* ih, int inIndex, const char* filename, int count_x, int count_y, int count_z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || !filename) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (count_x==0 || count_y==0 || count_z==0) ds->dsX->Read(filename); else ds->dsX->Read(filename, count_x, count_y, count_z); ds->dsCount = ds->dsX->nx*ds->dsX->ny*ds->dsX->nz; ih->data->redraw = true; } void IupMglPlotSetFormula(Ihandle* ih, int inIndex, const char* formulaX, const char* formulaY, const char* formulaZ, int count) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || !formulaX) return; IdataSet* ds = &ih->data->dataSet[inIndex]; if (ds->dsDim >= 2 && !formulaY) return; if (ds->dsDim == 3 && !formulaZ) return; count = count>0? count: ds->dsCount; if (count != ds->dsCount) { ds->dsCount = count; ds->dsX->Create(count); if (ds->dsY) ds->dsY->Create(count); if (ds->dsZ) ds->dsZ->Create(count); } mglGraph* gr = new mglGraph(0, 10, 10); mglPoint Min(iupAttribGetDouble(ih, "FORMULA_XMIN"), iupAttribGetDouble(ih, "FORMULA_YMIN"), iupAttribGetDouble(ih, "FORMULA_YMIN")); mglPoint Max(iupAttribGetDouble(ih, "FORMULA_XMAX"), iupAttribGetDouble(ih, "FORMULA_YMAX"), iupAttribGetDouble(ih, "FORMULA_YMAX")); gr->SetRange('x', Min.x, Max.x); gr->SetRange('y', Min.y, Max.y); gr->SetRange('z', Min.z, Max.z); ds->dsX->Fill(gr->Self(), formulaX, ""); if (ds->dsY) ds->dsY->Fill(gr->Self(), formulaY, ""); if (ds->dsZ) ds->dsZ->Fill(gr->Self(), formulaZ, ""); delete gr; ih->data->redraw = true; } void IupMglPlotSetFromFormula(Ihandle* ih, int inIndex, const char* formula, int count_x, int count_y, int count_z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if(inIndex > (ih->data->dataSetCount-1) || inIndex < 0 || !formula) return; IdataSet* ds = &ih->data->dataSet[inIndex]; int nx = count_x>0? count_x: ds->dsX->nx; int ny = count_y>0? count_y: ds->dsX->ny; int nz = count_z>0? count_z: ds->dsX->nz; if (nx != ds->dsX->nx || ny != ds->dsX->ny || nz != ds->dsX->nz) ds->dsX->Create(nx, ny, nz); mglGraph* gr = new mglGraph(0, 10, 10); mglPoint Min(iupAttribGetDouble(ih, "FORMULA_XMIN"), iupAttribGetDouble(ih, "FORMULA_YMIN"), iupAttribGetDouble(ih, "FORMULA_YMIN")); mglPoint Max(iupAttribGetDouble(ih, "FORMULA_XMAX"), iupAttribGetDouble(ih, "FORMULA_YMAX"), iupAttribGetDouble(ih, "FORMULA_YMAX")); gr->SetRange('x', Min.x, Max.x); gr->SetRange('y', Min.y, Max.y); gr->SetRange('z', Min.z, Max.z); ds->dsX->Fill(gr->Self(), formula, ""); ds->dsCount = ds->dsX->nx*ds->dsX->ny*ds->dsX->nz; delete gr; ih->data->redraw = true; } void IupMglPlotTransform(Ihandle* ih, double x, double y, double z, int *ix, int *iy) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; mglPoint p = ih->data->mgl->CalcScr(mglPoint(x, y, z)); if (ix) *ix = (int)p.x; if (iy) *iy = (int)p.y; } void IupMglPlotTransformTo(Ihandle* ih, int ix, int iy, double *x, double *y, double *z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; mglPoint p = ih->data->mgl->CalcXYZ(ix, iy); if (x) *x = p.x; if (y) *y = p.y; if (z) *z = p.z; } void IupMglPlotPaintTo(Ihandle* ih, const char* format, int w, int h, double dpi, void *data) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; if (!format || !data) return; int old_w = ih->data->w; int old_h = ih->data->h; double old_dpi = ih->data->dpi; if (dpi == 0) dpi = old_dpi; if (w == 0) w = old_w; if (h == 0) h = old_h; ih->data->w = w; ih->data->h = h; ih->data->dpi = dpi; if (*format == 'E') //EPS { char* filename = (char*)data; mglGraph* gr = new mglGraph(0, w, h); iMglPlotDrawPlot(ih, gr); gr->WriteEPS(filename, "IupMglPlot"); delete gr; } else if (*format == 'S') //SVG { char* filename = (char*)data; mglGraph* gr = new mglGraph(0, w, h); iMglPlotDrawPlot(ih, gr); gr->WriteSVG(filename, "IupMglPlot"); delete gr; } else if (*format == 'R') //RGB { int alpha = 0; const unsigned char *input_bits; unsigned char* output_bits = (unsigned char*)data; if (*(format+3) == 'A') alpha = 1; mglGraph* gr = new mglGraph(0, w, h); iMglPlotDrawPlot(ih, gr); if (alpha) input_bits = gr->GetRGBA(); else input_bits = gr->GetRGB(); memcpy(output_bits, input_bits, w*h*(alpha? 4:3)); delete gr; } ih->data->w = old_w; ih->data->h = old_h; ih->data->dpi = old_dpi; } void IupMglPlotDrawMark(Ihandle* ih, double x, double y, double z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; mglGraph* gr = (mglGraph*)iupAttribGet(ih, "_IUP_MGLPLOT_GRAPH"); if (!gr) return; char style[64] = ""; char* value = iupAttribGetStr(ih, "DRAWCOLOR"); mglColor markColor; if (!value) markColor = ih->data->fgColor; else iMglPlotSetColor(ih, value, markColor); iMglPlotAddStyleColor(ih, style, markColor); value = iupAttribGetStr(ih, "DRAWMARKSTYLE"); char markstyle = 'x'; iMglPlotSetMarkStyle(ih, value, markstyle); iMglPlotAddStyleMark(style, markstyle); double marksize = iupAttribGetDouble(ih, "DRAWMARKSIZE"); if (marksize <= 0) marksize = 0.02; gr->SetMarkSize(marksize); gr->Mark(mglPoint(x, y, z), style); } void IupMglPlotDrawLine(Ihandle* ih, double x1, double y1, double z1, double x2, double y2, double z2) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; mglGraph* gr = (mglGraph*)iupAttribGet(ih, "_IUP_MGLPLOT_GRAPH"); if (!gr) return; char style[64] = ""; char* value = iupAttribGetStr(ih, "DRAWCOLOR"); mglColor lineColor; if (!value) lineColor = ih->data->fgColor; else iMglPlotSetColor(ih, value, lineColor); iMglPlotAddStyleColor(ih, style, lineColor); value = iupAttribGetStr(ih, "DRAWLINESTYLE"); char linestyle = '-'; iMglPlotSetLineStyle(ih, value, linestyle); int linewidth = iupAttribGetInt(ih, "DRAWLINEWIDTH"); iMglPlotAddStyleLine(style, linestyle, linewidth); gr->Line(mglPoint(x1, y1, z1), mglPoint(x2, y2, z2), style); } void IupMglPlotDrawText(Ihandle* ih, const char* text, double x, double y, double z) { iupASSERT(iupObjectCheck(ih)); if (!iupObjectCheck(ih)) return; if (ih->iclass->nativetype != IUP_TYPECANVAS || !IupClassMatch(ih, "mglplot")) return; mglGraph* gr = (mglGraph*)iupAttribGet(ih, "_IUP_MGLPLOT_GRAPH"); if (!gr) return; char style[64] = ""; char* value = iupAttribGetStr(ih, "DRAWCOLOR"); mglColor textColor; if (!value) textColor = ih->data->fgColor; else iMglPlotSetColor(ih, value, textColor); iMglPlotAddStyleColor(ih, style, textColor); value = iupAttribGetStr(ih, "DRAWFONT"); if (value) iMglPlotConfigFontDef(ih, gr, value); char fontstyle[32] = ""; value = iupAttribGetStr(ih, "DRAWFONTSTYLE"); iMglPlotAddStyleFont(fontstyle, value); value = iupAttribGetStr(ih, "DRAWFONTSIZE"); double fontsizefactor = 1.0; iupStrToDouble(value, &fontsizefactor); iMglPlotConfigFont(ih, gr, NULL, fontstyle, fontsizefactor); gr->Puts(mglPoint(x, y, z), text, style); } /****************************************************************************** Canvas Callbacks ******************************************************************************/ static void iMglPlotZoom(Ihandle *ih, double factor) { double rh = ih->data->y2 - ih->data->y1; double ry = (rh * factor) / (double)ih->data->h; double rw = ih->data->x2 - ih->data->x1; double rx = (rw * factor) / (double)ih->data->w; ih->data->y1 += ry; ih->data->y2 -= ry; ih->data->x1 += rx; ih->data->x2 -= rx; //TODO: temporary-commented while adjusting sizes //if (ih->data->x1 < 0) ih->data->x1 = 0; //if (ih->data->y1 < 0) ih->data->y1 = 0; //if (ih->data->x2 > 1.0) ih->data->x2 = 1.0; //if (ih->data->y2 > 1.0) ih->data->y2 = 1.0; } static void iMglPlotPanY(Ihandle *ih, double yoffset) { double rh = ih->data->y2 - ih->data->y1; double ry = (rh * yoffset) / (double)ih->data->h; if (ih->data->y1 + ry < 0) ry = -ih->data->y1; if (ih->data->y2 + ry > 1.0) ry = 1.0 - ih->data->y2; ih->data->y1 += ry; ih->data->y2 += ry; } static void iMglPlotPanX(Ihandle *ih, double xoffset) { double rw = ih->data->x2 - ih->data->x1; double rx = (rw * xoffset) / (double)ih->data->w; if (ih->data->x1 + rx < 0) rx = -ih->data->x1; if (ih->data->x2 + rx > 1.0) rx = 1.0 - ih->data->x2; ih->data->x1 += rx; ih->data->x2 += rx; } static void iMglPlotRotate(double &angle, double delta) { angle += delta; // Keep between -360:+360 just to return a nice value in the getattrib method angle = fmod(angle, 360.0); } static int iMglPlotResize_CB(Ihandle* ih, int width, int height) { ih->data->redraw = true; ih->data->w = width; ih->data->h = height; ih->data->dpi = IupGetDouble(NULL, "SCREENDPI"); iMglPlotInitOpenGL2D(ih); ih->data->mgl->SetSize(width, height); return IUP_DEFAULT; } static int iMglPlotRedraw_CB(Ihandle* ih) { iMglPlotRepaint(ih, 0, 1); /* full redraw only if nothing changed */ return IUP_DEFAULT; } static int iMglPlotMouseButton_CB(Ihandle* ih, int b, int press, int x, int y, char* status) { if (press) /* Any Button pressed */ { /* Initial (x,y) */ ih->data->last_x = (double)x; ih->data->last_y = (double)y; } if (iup_isdouble(status)) /* Double-click: restore interaction default values */ { iMglPlotResetInteraction(ih); iMglPlotRepaint(ih, 1, 1); } (void)b; return IUP_DEFAULT; } static int iMglPlotMouseMove_CB(Ihandle* ih, int x, int y, char *status) { double cur_x = (double)x; double cur_y = (double)y; if (iup_isbutton3(status)) { // This is the same computation done in MathGL widgets double ff = 240.0 / sqrt(double(ih->data->w * ih->data->h)); double deltaZ = (ih->data->last_x - cur_x) * ff; double deltaX = (ih->data->last_y - cur_y) * ff; iMglPlotRotate(ih->data->rotX, deltaX); iMglPlotRotate(ih->data->rotZ, deltaZ); iMglPlotRepaint(ih, 1, 1); } else if(iup_isbutton1(status)) { if (iup_iscontrol(status)) { /* Zoom with vertical movement */ double factor = 10.0 * (ih->data->last_y - cur_y); iMglPlotZoom(ih, factor); } else { /* Pan */ double xoffset = ih->data->last_x - cur_x; double yoffset = cur_y - ih->data->last_y; /* Inverted because Y in IUP is top-down */ iMglPlotPanX(ih, xoffset); iMglPlotPanY(ih, yoffset); } iMglPlotRepaint(ih, 1, 1); } ih->data->last_x = cur_x; ih->data->last_y = cur_y; return IUP_DEFAULT; } static int iMglPlotWheel_CB(Ihandle* ih, float delta) { if(delta < 0) /* Zoom In */ { iMglPlotZoom(ih, 50.0); iMglPlotRepaint(ih, 1, 1); } else if(delta > 0) /* Zoom Out */ { iMglPlotZoom(ih, -50.0); iMglPlotRepaint(ih, 1, 1); } return IUP_DEFAULT; } static int iMglPlotKeyPress_CB(Ihandle* ih, int c, int press) { if (!press) return IUP_DEFAULT; switch(c) { /* Restore interaction default values */ case K_HOME: iMglPlotResetInteraction(ih); break; /* Pan */ case K_cUP: case K_UP: if (c == K_cUP) iMglPlotPanY(ih, -10.0); else iMglPlotPanY(ih, -1.0); break; case K_cDOWN: case K_DOWN: if (c == K_cDOWN) iMglPlotPanY(ih, 10.0); else iMglPlotPanY(ih, 1.0); break; case K_cLEFT: case K_LEFT: if (c == K_cLEFT) iMglPlotPanX(ih, 10.0); else iMglPlotPanX(ih, 1.0); break; case K_cRIGHT: case K_RIGHT: if (c == K_cRIGHT) iMglPlotPanX(ih, -10.0); else iMglPlotPanX(ih, -1.0); break; /* Zoom */ case K_plus: iMglPlotZoom(ih, 10.0); break; case K_minus: iMglPlotZoom(ih, -10.0); break; /* Rotation */ case K_A: case K_a: iMglPlotRotate(ih->data->rotY, +1.0); // 1 degree break; case K_D: case K_d: iMglPlotRotate(ih->data->rotY, -1.0); break; case K_W: case K_w: iMglPlotRotate(ih->data->rotX, +1.0); break; case K_S: case K_s: iMglPlotRotate(ih->data->rotX, -1.0); break; case K_E: case K_e: iMglPlotRotate(ih->data->rotZ, +1.0); break; case K_Q: case K_q: iMglPlotRotate(ih->data->rotZ, -1.0); break; default: return IUP_DEFAULT; } iMglPlotRepaint(ih, 1, 1); return IUP_IGNORE; /* ignore processed keys */ } /****************************************************************************** Class Methods ******************************************************************************/ static void iMglPlotDestroyMethod(Ihandle* ih) { int i; /* PLOT End for the current stream */ for(i = 0; i < ih->data->dataSetCount; i++) iMglPlotRemoveDataSet(&ih->data->dataSet[i]); free(ih->data->dataSet); delete ih->data->mgl; } static int iMglPlotCreateMethod(Ihandle* ih, void **params) { (void)params; /* free the data allocated by IupCanvas */ free(ih->data); ih->data = iupALLOCCTRLDATA(); ih->data->dataSetMaxCount = 5; ih->data->dataSet = (IdataSet*)malloc(sizeof(IdataSet)*ih->data->dataSetMaxCount); memset(ih->data->dataSet, 0, sizeof(IdataSet)*ih->data->dataSetMaxCount); ih->data->dataSetCurrent = -1; /* IupCanvas callbacks */ IupSetCallback(ih, "RESIZE_CB", (Icallback)iMglPlotResize_CB); IupSetCallback(ih, "ACTION", (Icallback)iMglPlotRedraw_CB); IupSetCallback(ih, "BUTTON_CB", (Icallback)iMglPlotMouseButton_CB); IupSetCallback(ih, "WHEEL_CB", (Icallback)iMglPlotWheel_CB); IupSetCallback(ih, "KEYPRESS_CB", (Icallback)iMglPlotKeyPress_CB); IupSetCallback(ih, "MOTION_CB", (Icallback)iMglPlotMouseMove_CB); IupSetAttribute(ih, "BUFFER", "DOUBLE"); ih->data->redraw = true; ih->data->w = 1; ih->data->h = 1; ih->data->mgl = new mglGraph(0, ih->data->w, ih->data->h); // Default values iMglPlotReset(ih); return IUP_NOERROR; } static Iclass* iMglPlotNewClass(void) { Iclass* ic = iupClassNew(iupRegisterFindClass("glcanvas")); ic->name = "mglplot"; ic->cons = "MglPlot"; ic->format = NULL; /* none */ ic->nativetype = IUP_TYPECANVAS; ic->childtype = IUP_CHILDNONE; ic->is_interactive = 1; /* Class functions */ ic->New = iMglPlotNewClass; ic->Create = iMglPlotCreateMethod; ic->Destroy = iMglPlotDestroyMethod; /* IupPPlot Callbacks */ iupClassRegisterCallback(ic, "POSTDRAW_CB", ""); iupClassRegisterCallback(ic, "PREDRAW_CB", ""); /* Visual */ iupClassRegisterAttribute(ic, "BGCOLOR", iMglPlotGetBGColorAttrib, iMglPlotSetBGColorAttrib, "255 255 255", NULL, IUPAF_NOT_MAPPED); /* overwrite canvas implementation, set a system default to force a new default */ iupClassRegisterAttribute(ic, "FGCOLOR", iMglPlotGetFGColorAttrib, iMglPlotSetFGColorAttrib, IUPAF_SAMEASSYSTEM, "0 0 0", IUPAF_NOT_MAPPED); /* IupMglPlot only */ iupClassRegisterAttribute(ic, "REDRAW", NULL, iMglPlotSetRedrawAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ALPHA", iMglPlotGetAlphaAttrib, iMglPlotSetAlphaAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TRANSPARENT", iMglPlotGetTransparentAttrib, iMglPlotSetTransparentAttrib, IUPAF_SAMEASSYSTEM, "No", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "OPENGL", iMglPlotGetOpenGLAttrib, iMglPlotSetOpenGLAttrib, IUPAF_SAMEASSYSTEM, "No", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ANTIALIAS", iMglPlotGetAntialiasAttrib, iMglPlotSetAntialiasAttrib, IUPAF_SAMEASSYSTEM, "No", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "RESET", NULL, iMglPlotSetResetAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ERRORMESSAGE", iMglPlotGetErrorMessageAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SUPPRESSWARNING", NULL, iMglPlotSetSuppressWarningAttrib, NULL, NULL, IUPAF_WRITEONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MGLGRAPH", iMglPlotGetMglGraphAttrib, NULL, NULL, NULL, IUPAF_NO_STRING | IUPAF_READONLY | IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MARGINLEFT", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MARGINRIGHT", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MARGINTOP", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "MARGINBOTTOM", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TITLE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TITLECOLOR", iMglPlotGetTitleColorAttrib, iMglPlotSetTitleColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED); iupClassRegisterAttribute(ic, "TITLEFONTSIZE", iMglPlotGetTitleFontSizeAttrib, iMglPlotSetTitleFontSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "TITLEFONTSTYLE", iMglPlotGetTitleFontStyleAttrib, iMglPlotSetTitleFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGEND", iMglPlotGetLegendShowAttrib, iMglPlotSetLegendShowAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGENDSHOW", iMglPlotGetLegendShowAttrib, iMglPlotSetLegendShowAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); // for IupPPlot compatibility iupClassRegisterAttribute(ic, "LEGENDBOX", iMglPlotGetLegendBoxAttrib, iMglPlotSetLegendBoxAttrib, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGENDPOS", iMglPlotGetLegendPosAttrib, iMglPlotSetLegendPosAttrib, IUPAF_SAMEASSYSTEM, "TOPRIGHT", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGENDFONTSIZE", iMglPlotGetLegendFontSizeAttrib, iMglPlotSetLegendFontSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGENDFONTSTYLE", iMglPlotGetLegendFontStyleAttrib, iMglPlotSetLegendFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LEGENDCOLOR", iMglPlotGetLegendColorAttrib, iMglPlotSetLegendColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "GRIDLINESTYLE", iMglPlotGetGridLineStyleAttrib, iMglPlotSetGridLineStyleAttrib, IUPAF_SAMEASSYSTEM, "CONTINUOUS", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "GRIDCOLOR", iMglPlotGetGridColorAttrib, iMglPlotSetGridColorAttrib, IUPAF_SAMEASSYSTEM, "200 200 200", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "GRID", iMglPlotGetGridAttrib, iMglPlotSetGridAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "REMOVE", NULL, iMglPlotSetRemoveAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CLEAR", NULL, iMglPlotSetClearAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COUNT", iMglPlotGetCountAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CURRENT", iMglPlotGetCurrentAttrib, iMglPlotSetCurrentAttrib, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_LINESTYLE", iMglPlotGetDSLineStyleAttrib, iMglPlotSetDSLineStyleAttrib, IUPAF_SAMEASSYSTEM, "CONTINUOUS", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_LINEWIDTH", iMglPlotGetDSLineWidthAttrib, iMglPlotSetDSLineWidthAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_MARKSTYLE", iMglPlotGetDSMarkStyleAttrib, iMglPlotSetDSMarkStyleAttrib, IUPAF_SAMEASSYSTEM, "X", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_MARKSIZE", iMglPlotGetDSMarkSizeAttrib, iMglPlotSetDSMarkSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_SHOWMARKS", iMglPlotGetDSShowMarksAttrib, iMglPlotSetDSShowMarksAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_LEGEND", iMglPlotGetDSLegendAttrib, iMglPlotSetDSLegendAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_COLOR", iMglPlotGetDSColorAttrib, iMglPlotSetDSColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_SHOWVALUES", iMglPlotGetDSShowValuesAttrib, iMglPlotSetDSShowValuesAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_MODE", iMglPlotGetDSModeAttrib, iMglPlotSetDSModeAttrib, IUPAF_SAMEASSYSTEM, "LINE", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_REMOVE", NULL, iMglPlotSetDSRemoveAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_COUNT", iMglPlotGetDSCountAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_DIMENSION", iMglPlotGetDSDimAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_REARRANGE", NULL, iMglPlotSetDSRearrangeAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DS_SPLIT", NULL, iMglPlotSetDSSplitAttrib, NULL, NULL, IUPAF_WRITEONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DATAGRID", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "GRADLINESCOUNT", NULL, NULL, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXIALCOUNT", NULL, NULL, IUPAF_SAMEASSYSTEM, "3", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CONTOURFILLED", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CONTOURLABELS", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CONTOURCOUNT", NULL, NULL, IUPAF_SAMEASSYSTEM, "7", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DIR", NULL, NULL, IUPAF_SAMEASSYSTEM, "Y", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CLOUDLOW", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SLICEX", NULL, NULL, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SLICEY", NULL, NULL, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SLICEZ", NULL, NULL, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SLICEDIR", NULL, NULL, IUPAF_SAMEASSYSTEM, "XYZ", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PROJECTVALUEX", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PROJECTVALUEY", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PROJECTVALUEZ", NULL, NULL, IUPAF_SAMEASSYSTEM, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PROJECT", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ISOCOUNT", NULL, NULL, IUPAF_SAMEASSYSTEM, "3", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "BARWIDTH", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "RADARSHIFT", NULL, NULL, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "PIECHART", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "LIGHT", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COLORSCHEME", NULL, NULL, IUPAF_SAMEASSYSTEM, "BbcyrR", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COLORBAR", NULL, NULL, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COLORBARPOS", NULL, NULL, IUPAF_SAMEASSYSTEM, "RIGHT", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COLORBARRANGE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "COLORBARAXISTICKS", NULL, NULL, IUPAF_SAMEASSYSTEM, "Z", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "BOX", iMglPlotGetBoxAttrib, iMglPlotSetBoxAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "BOXTICKS", iMglPlotGetBoxTicksAttrib, iMglPlotSetBoxTicksAttrib, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "BOXCOLOR", iMglPlotGetBoxColorAttrib, iMglPlotSetBoxColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XLABEL", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YLABEL", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZLABEL", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XLABELCENTERED", iMglPlotGetAxisXLabelCenteredAttrib, iMglPlotSetAxisXLabelCenteredAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YLABELCENTERED", iMglPlotGetAxisYLabelCenteredAttrib, iMglPlotSetAxisYLabelCenteredAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZLABELCENTERED", iMglPlotGetAxisZLabelCenteredAttrib, iMglPlotSetAxisZLabelCenteredAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XLABELPOSITION", iMglPlotGetAxisXLabelPositionAttrib, iMglPlotSetAxisXLabelPositionAttrib, IUPAF_SAMEASSYSTEM, "CENTER", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YLABELPOSITION", iMglPlotGetAxisYLabelPositionAttrib, iMglPlotSetAxisYLabelPositionAttrib, IUPAF_SAMEASSYSTEM, "CENTER", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZLABELPOSITION", iMglPlotGetAxisZLabelPositionAttrib, iMglPlotSetAxisZLabelPositionAttrib, IUPAF_SAMEASSYSTEM, "CENTER", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XLABELROTATION", iMglPlotGetAxisXLabelRotationAttrib, iMglPlotSetAxisXLabelRotationAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YLABELROTATION", iMglPlotGetAxisYLabelRotationAttrib, iMglPlotSetAxisYLabelRotationAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZLABELROTATION", iMglPlotGetAxisZLabelRotationAttrib, iMglPlotSetAxisZLabelRotationAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XCOLOR", iMglPlotGetAxisXColorAttrib, iMglPlotSetAxisXColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YCOLOR", iMglPlotGetAxisYColorAttrib, iMglPlotSetAxisYColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZCOLOR", iMglPlotGetAxisZColorAttrib, iMglPlotSetAxisZColorAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XAUTOMIN", iMglPlotGetAxisXAutoMinAttrib, iMglPlotSetAxisXAutoMinAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YAUTOMIN", iMglPlotGetAxisYAutoMinAttrib, iMglPlotSetAxisYAutoMinAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZAUTOMIN", iMglPlotGetAxisZAutoMinAttrib, iMglPlotSetAxisZAutoMinAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XAUTOMAX", iMglPlotGetAxisXAutoMaxAttrib, iMglPlotSetAxisXAutoMaxAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YAUTOMAX", iMglPlotGetAxisYAutoMaxAttrib, iMglPlotSetAxisYAutoMaxAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZAUTOMAX", iMglPlotGetAxisZAutoMaxAttrib, iMglPlotSetAxisZAutoMaxAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XMIN", iMglPlotGetAxisXMinAttrib, iMglPlotSetAxisXMinAttrib, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YMIN", iMglPlotGetAxisYMinAttrib, iMglPlotSetAxisYMinAttrib, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZMIN", iMglPlotGetAxisZMinAttrib, iMglPlotSetAxisZMinAttrib, IUPAF_SAMEASSYSTEM, "-1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XMAX", iMglPlotGetAxisXMaxAttrib, iMglPlotSetAxisXMaxAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YMAX", iMglPlotGetAxisYMaxAttrib, iMglPlotSetAxisYMaxAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZMAX", iMglPlotGetAxisZMaxAttrib, iMglPlotSetAxisZMaxAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XREVERSE", iMglPlotGetAxisXReverseAttrib, iMglPlotSetAxisXReverseAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YREVERSE", iMglPlotGetAxisYReverseAttrib, iMglPlotSetAxisYReverseAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZREVERSE", iMglPlotGetAxisZReverseAttrib, iMglPlotSetAxisZReverseAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_X", iMglPlotGetAxisXShowAttrib, iMglPlotSetAxisXShowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_Y", iMglPlotGetAxisYShowAttrib, iMglPlotSetAxisYShowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_Z", iMglPlotGetAxisZShowAttrib, iMglPlotSetAxisZShowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XARROW", iMglPlotGetAxisXShowArrowAttrib, iMglPlotSetAxisXShowArrowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YARROW", iMglPlotGetAxisYShowArrowAttrib, iMglPlotSetAxisYShowArrowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZARROW", iMglPlotGetAxisZShowArrowAttrib, iMglPlotSetAxisZShowArrowAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XCROSSORIGIN", iMglPlotGetAxisXCrossOriginAttrib, iMglPlotSetAxisXCrossOriginAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YCROSSORIGIN", iMglPlotGetAxisYCrossOriginAttrib, iMglPlotSetAxisYCrossOriginAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZCROSSORIGIN", iMglPlotGetAxisZCrossOriginAttrib, iMglPlotSetAxisZCrossOriginAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XORIGIN", iMglPlotGetAxisXOriginAttrib, iMglPlotSetAxisXOriginAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YORIGIN", iMglPlotGetAxisYOriginAttrib, iMglPlotSetAxisYOriginAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZORIGIN", iMglPlotGetAxisZOriginAttrib, iMglPlotSetAxisZOriginAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XSCALE", iMglPlotGetAxisXScaleAttrib, iMglPlotSetAxisXScaleAttrib, IUPAF_SAMEASSYSTEM, "LIN", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YSCALE", iMglPlotGetAxisYScaleAttrib, iMglPlotSetAxisYScaleAttrib, IUPAF_SAMEASSYSTEM, "LIN", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZSCALE", iMglPlotGetAxisZScaleAttrib, iMglPlotSetAxisZScaleAttrib, IUPAF_SAMEASSYSTEM, "LIN", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XFONTSIZE", iMglPlotGetAxisXFontSizeAttrib, iMglPlotSetAxisXFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YFONTSIZE", iMglPlotGetAxisYFontSizeAttrib, iMglPlotSetAxisYFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YFONTSIZE", iMglPlotGetAxisZFontSizeAttrib, iMglPlotSetAxisZFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XFONTSTYLE", iMglPlotGetAxisXFontStyleAttrib, iMglPlotSetAxisXFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YFONTSTYLE", iMglPlotGetAxisYFontStyleAttrib, iMglPlotSetAxisYFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZFONTSTYLE", iMglPlotGetAxisZFontStyleAttrib, iMglPlotSetAxisZFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICK", iMglPlotGetAxisXTickAttrib, iMglPlotSetAxisXTickAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICK", iMglPlotGetAxisYTickAttrib, iMglPlotSetAxisYTickAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICK", iMglPlotGetAxisZTickAttrib, iMglPlotSetAxisZTickAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKVALUES", iMglPlotGetAxisXTickShowValuesAttrib, iMglPlotSetAxisXTickShowValuesAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKVALUES", iMglPlotGetAxisYTickShowValuesAttrib, iMglPlotSetAxisYTickShowValuesAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKVALUES", iMglPlotGetAxisZTickShowValuesAttrib, iMglPlotSetAxisZTickShowValuesAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKVALUESROTATION", iMglPlotGetAxisXTickValuesRotationAttrib, iMglPlotSetAxisXTickValuesRotationAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKVALUESROTATION", iMglPlotGetAxisYTickValuesRotationAttrib, iMglPlotSetAxisYTickValuesRotationAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKVALUESROTATION", iMglPlotGetAxisZTickValuesRotationAttrib, iMglPlotSetAxisZTickValuesRotationAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKFORMAT", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKFORMAT", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKFORMAT", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKFONTSIZE", iMglPlotGetAxisXTickFontSizeAttrib, iMglPlotSetAxisXTickFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKFONTSIZE", iMglPlotGetAxisYTickFontSizeAttrib, iMglPlotSetAxisYTickFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKFONTSIZE", iMglPlotGetAxisZTickFontSizeAttrib, iMglPlotSetAxisZTickFontSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKFONTSTYLE", iMglPlotGetAxisXTickFontStyleAttrib, iMglPlotSetAxisXTickFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKFONTSTYLE", iMglPlotGetAxisYTickFontStyleAttrib, iMglPlotSetAxisYTickFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKFONTSTYLE", iMglPlotGetAxisZTickFontStyleAttrib, iMglPlotSetAxisZTickFontStyleAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XAUTOTICK", iMglPlotGetAxisXTickAutoAttrib, iMglPlotSetAxisXTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YAUTOTICK", iMglPlotGetAxisYTickAutoAttrib, iMglPlotSetAxisYTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZAUTOTICK", iMglPlotGetAxisZTickAutoAttrib, iMglPlotSetAxisZTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKAUTO", iMglPlotGetAxisXTickAutoAttrib, iMglPlotSetAxisXTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKAUTO", iMglPlotGetAxisYTickAutoAttrib, iMglPlotSetAxisYTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKAUTO", iMglPlotGetAxisZTickAutoAttrib, iMglPlotSetAxisZTickAutoAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKMAJORSPAN", iMglPlotGetAxisXTickMajorSpanAttrib, iMglPlotSetAxisXTickMajorSpanAttrib, IUPAF_SAMEASSYSTEM, "-5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKMAJORSPAN", iMglPlotGetAxisYTickMajorSpanAttrib, iMglPlotSetAxisYTickMajorSpanAttrib, IUPAF_SAMEASSYSTEM, "-5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKMAJORSPAN", iMglPlotGetAxisZTickMajorSpanAttrib, iMglPlotSetAxisZTickMajorSpanAttrib, IUPAF_SAMEASSYSTEM, "-5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKDIVISION", iMglPlotGetAxisXTickMinorDivisionAttrib, iMglPlotSetAxisXTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKDIVISION", iMglPlotGetAxisYTickMinorDivisionAttrib, iMglPlotSetAxisYTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKDIVISION", iMglPlotGetAxisZTickMinorDivisionAttrib, iMglPlotSetAxisZTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKMINORDIVISION", iMglPlotGetAxisXTickMinorDivisionAttrib, iMglPlotSetAxisXTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKMINORDIVISION", iMglPlotGetAxisYTickMinorDivisionAttrib, iMglPlotSetAxisYTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKMINORDIVISION", iMglPlotGetAxisZTickMinorDivisionAttrib, iMglPlotSetAxisZTickMinorDivisionAttrib, IUPAF_SAMEASSYSTEM, "5", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XAUTOTICKSIZE", iMglPlotGetAxisXTickAutoSizeAttrib, iMglPlotSetAxisXTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YAUTOTICKSIZE", iMglPlotGetAxisYTickAutoSizeAttrib, iMglPlotSetAxisYTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZAUTOTICKSIZE", iMglPlotGetAxisZTickAutoSizeAttrib, iMglPlotSetAxisZTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKAUTOSIZE", iMglPlotGetAxisXTickAutoSizeAttrib, iMglPlotSetAxisXTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKAUTOSIZE", iMglPlotGetAxisYTickAutoSizeAttrib, iMglPlotSetAxisYTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKAUTOSIZE", iMglPlotGetAxisZTickAutoSizeAttrib, iMglPlotSetAxisZTickAutoSizeAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKMAJORSIZE", iMglPlotGetAxisXTickMajorSizeAttrib, iMglPlotSetAxisXTickMajorSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKMAJORSIZE", iMglPlotGetAxisYTickMajorSizeAttrib, iMglPlotSetAxisYTickMajorSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKMAJORSIZE", iMglPlotGetAxisZTickMajorSizeAttrib, iMglPlotSetAxisZTickMajorSizeAttrib, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_XTICKMINORSIZE", iMglPlotGetAxisXTickMinorSizeAttrib, iMglPlotSetAxisXTickMinorSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_YTICKMINORSIZE", iMglPlotGetAxisYTickMinorSizeAttrib, iMglPlotSetAxisYTickMinorSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "AXS_ZTICKMINORSIZE", iMglPlotGetAxisZTickMinorSizeAttrib, iMglPlotSetAxisZTickMinorSizeAttrib, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWCOLOR", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWMARKSTYLE", NULL, NULL, IUPAF_SAMEASSYSTEM, "X", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWMARKSIZE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWLINESTYLE", NULL, NULL, IUPAF_SAMEASSYSTEM, "CONTINUOUS", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWLINEWIDTH", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWFONTSTYLE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "DRAWFONTSIZE", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_XMIN", NULL, NULL, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_YMIN", NULL, NULL, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_ZMIN", NULL, NULL, IUPAF_SAMEASSYSTEM, "0", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_XMAX", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_YMAX", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FORMULA_ZMAX", NULL, NULL, IUPAF_SAMEASSYSTEM, "1", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ZOOM", iMglPlotGetZoomAttrib, iMglPlotSetZoomAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "ROTATE", iMglPlotGetRotateAttrib, iMglPlotSetRotateAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); return ic; } Ihandle* IupMglPlot(void) { return IupCreate("mglplot"); } static int iMglLabelPostDraw_CB(Ihandle* ih) { char* value = iupAttribGet(ih, "LABELTITLE"); if (value) { iupAttribSet(ih, "DRAWFONT", iupAttribGetStr(ih, "LABELFONT")); iupAttribSet(ih, "DRAWFONTSTYLE", iupAttribGetStr(ih, "LABELFONTSTYLE")); iupAttribSet(ih, "DRAWFONTSIZE", iupAttribGetStr(ih, "LABELFONTSIZE")); IupMglPlotDrawText(ih, value, 0, -0.5, 0); } return IUP_DEFAULT; } static int iMglLabelCreateMethod(Ihandle* ih, void** params) { if (params && params[0]) iupAttribSetStr(ih, "LABELTITLE", (char*)(params[0])); IupSetAttribute(ih, "MARGINLEFT", "No"); IupSetAttribute(ih, "MARGINRIGHT", "No"); IupSetAttribute(ih, "MARGINTOP", "No"); IupSetAttribute(ih, "MARGINBOTTOM", "No"); IupSetAttribute(ih, "AXS_X", "No"); IupSetAttribute(ih, "AXS_Y", "No"); IupSetAttribute(ih, "AXS_Z", "No"); IupSetAttribute(ih, "EXPAND", "No"); IupSetAttribute(ih, "BORDER", "No"); IupSetCallback(ih, "POSTDRAW_CB", (Icallback)iMglLabelPostDraw_CB); return IUP_NOERROR; } static int iMglLabelMapMethod(Ihandle* ih) { if (!iupAttribGet(ih, "BGCOLOR")) IupSetStrAttribute(ih, "BGCOLOR", IupGetAttribute(iupChildTreeGetNativeParent(ih), "BGCOLOR")); return IUP_NOERROR; } static Iclass* iMglLabelNewClass(void) { Iclass* ic = iupClassNew(iupRegisterFindClass("mglplot")); ic->name = "mgllabel"; ic->cons = "MglLabel"; ic->format = "s"; /* one string */ ic->format_attr = "LABELTITLE"; ic->nativetype = IUP_TYPECANVAS; ic->childtype = IUP_CHILDNONE; ic->is_interactive = 0; /* Class functions */ ic->New = iMglLabelNewClass; ic->Create = iMglLabelCreateMethod; ic->Map = iMglLabelMapMethod; iupClassRegisterAttribute(ic, "LABELTITLE", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); return ic; } Ihandle* IupMglLabel(const char* title) { void *params[2]; params[0] = (void*)title; params[1] = NULL; return IupCreatev("mgllabel", params); } void IupMglPlotOpen(void) { if (!IupIsOpened()) return; IupGLCanvasOpen(); if (!IupGetGlobal("_IUP_MGLPLOT_OPEN")) { iupRegisterClass(iMglPlotNewClass()); iupRegisterClass(iMglLabelNewClass()); IupSetGlobal("_IUP_MGLPLOT_OPEN", "1"); } } /************************ TODO *********************************** Render Feedback? OpenMP UTF-8 New from PPlot: IupPPlotGetSample IupPPlotGetSampleStr New: attributes REMOVE and CURRENT in IupPPlot now also accepts the DS_NAME as value when setting. iupClassRegisterAttribute(ic, "SYNCVIEW", iPPlotGetSyncViewAttrib, iPPlotSetSyncViewAttrib, NULL, NULL, IUPAF_NO_INHERIT); New: PLOT_COUNT, PLOT_NUMCOL, PLOT_CURRENT, PLOT_INSERT and PLOT_REMOVE attributes for IupPPlot to support multiple plots in the same display area. New: PLOTBUTTON_CB and PLOTMOTION_CB calbacks for IupPPlot. Known Issues: - *** text render quality is poor - font size scale if canvas size is changed ------------------------------------ - Piechart depends on SetFunc - *** DrawValues text rotation not correctly computed - *** Logarithm scale crashes in DrawLabel - OpenGL mode makes some 3D modes affect 2D modes (Bars, Barh, Radar, ...) - *** OpenGL inicial size is smaller ------------------------------------ - (IUP) More tick options - (IUP) Improve Bar at origin - (IUP) TicksVal should follow ticks spacing configuration - (IUP) improve autoticks computation Other: AddLight and Fog Cutting Curvilinear coordinates Plots that need two datasets: BoxPlot, Region, Tens, Mark, Error, Flow, Pipe, Ring, Candle, OHLC, Tube, Tape, Torus, SurfC, TileS, Dew, Traj, Vect chart and bars can be combined in one plot (bars then can include above and fall) Reference datasets dataset can be a pointer to the previous data, so the same data can be displayed using different modes using the same memory Other Plots: Cones, ContV, TriPlot, QuadPlot Ternary Axis IupMglPlotDrawCurve and IupMglPlotDrawFace **************************************************************************************/