bool iupPlot::CalculateTickSpacing(const iupPlotRect &inRect, cdCanvas* canvas) { double theXRange = mAxisX.mMax - mAxisX.mMin; double theYRange = mAxisY.mMax - mAxisY.mMin; if (theXRange <= 0 || theYRange < 0) return false; // YRange can be 0, must adjust if (mAxisY.mAutoScaleMax && ((mAxisY.mMax != 0 && fabs(theYRange / mAxisY.mMax) < kRangeVerySmall) || theYRange == 0)) { double delta = 0.1; if (mAxisY.mMax != 0) delta *= fabs(mAxisY.mMax); mAxisY.mMax += delta; theYRange = mAxisY.mMax - mAxisY.mMin; } if (mAxisX.mTick.mAutoSpacing) { int theXFontHeight; SetFont(canvas, mAxisX.mTick.mFontStyle, mAxisX.mTick.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theXFontHeight, NULL, NULL); int theTextWidth; cdCanvasGetTextSize(canvas, "12345", &theTextWidth, NULL); double theDivGuess = inRect.mWidth / (kMajorTickXInitialFac*theTextWidth); if (!mAxisX.mTickIter->CalculateSpacing(theXRange, theDivGuess, mAxisX.mTick)) return false; } if (mAxisY.mTick.mAutoSpacing) { int theYFontHeight; SetFont(canvas, mAxisY.mTick.mFontStyle, mAxisY.mTick.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theYFontHeight, NULL, NULL); double theDivGuess = inRect.mHeight / (kMajorTickYInitialFac*theYFontHeight); if (!mAxisY.mTickIter->CalculateSpacing(theYRange, theDivGuess, mAxisY.mTick)) return false; } return true; }
void iupPlot::CalculateTickSize(cdCanvas* canvas, iupPlotTick &ioTick) { if (ioTick.mAutoSize) { int theFontHeight; SetFont(canvas, ioTick.mFontStyle, ioTick.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theFontHeight, NULL, NULL); ioTick.mMajorSize = theFontHeight / 2; ioTick.mMinorSize = theFontHeight / 4; } }
void wdCanvasGetFontDim(cdCanvas* canvas, double *max_width, double *height, double *ascent, double *descent) { double origin_x, origin_y, tmp = 0; double distance_x, distance_y; int font_max_width, font_height, font_ascent, font_descent; cdCanvasGetFontDim(canvas, &font_max_width, &font_height, &font_ascent, &font_descent); _wCanvas2World(canvas, 0, 0, origin_x, origin_y); _wCanvas2World(canvas, font_max_width, font_height, distance_x, distance_y); if (max_width) *max_width = fabs(distance_x - origin_x); if (height) *height = fabs(distance_y - origin_y); _wCanvas2World(canvas, tmp, font_ascent, tmp, distance_y); if (ascent) *ascent = fabs(distance_y - origin_y); _wCanvas2World(canvas, tmp, font_descent, tmp, distance_y); if (descent) *descent = fabs(distance_y - origin_y); }
void iupPlot::CalculateMargins(cdCanvas* canvas) { if (mBack.mMarginAuto.mTop) { mBack.mMargin.mTop = 0; if (mTitle.GetText() && mTitle.mAutoPos) { SetTitleFont(canvas); int theTextHeight; cdCanvasGetTextSize(canvas, mTitle.GetText(), NULL, &theTextHeight); mBack.mMargin.mTop += theTextHeight + 5 + theTextHeight/2; } else { if (mAxisY.mShow) { if (mAxisY.mShowArrow && !mAxisY.mReverse) mBack.mMargin.mTop += mAxisY.mTick.mMinorSize + 2 + 5; // size of the arrow if (mAxisY.mTick.mShowNumber) { if (mAxisY.mTick.mRotateNumber) { int theYTickNumberHeight; mAxisY.GetTickNumberSize(canvas, NULL, &theYTickNumberHeight); mBack.mMargin.mTop += theYTickNumberHeight / 2; } else { int theYTickNumberWidth; mAxisY.GetTickNumberSize(canvas, &theYTickNumberWidth, NULL); mBack.mMargin.mTop += theYTickNumberWidth / 2; } } } } } if (mBack.mMarginAuto.mBottom) { mBack.mMargin.mBottom = 0; if (mAxisX.mShow && !mAxisX.mCrossOrigin) { mBack.mMargin.mBottom += mAxisX.mTick.mMajorSize; if (mAxisX.mTick.mShowNumber) { if (mAxisX.mTick.mRotateNumber) { int theXTickNumberWidth; mAxisX.GetTickNumberSize(canvas, &theXTickNumberWidth, NULL); mBack.mMargin.mBottom += theXTickNumberWidth; } else { int theXTickNumberHeight; mAxisX.GetTickNumberSize(canvas, NULL, &theXTickNumberHeight); mBack.mMargin.mBottom += theXTickNumberHeight; } } if (mAxisX.GetLabel()) { int theXFontHeight; SetFont(canvas, mAxisX.mFontStyle, mAxisX.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theXFontHeight, NULL, NULL); mBack.mMargin.mBottom += theXFontHeight + theXFontHeight / 10; } } if (mAxisY.mShow) { if (mAxisY.mTick.mShowNumber) { if (mAxisY.mTick.mRotateNumber) { int theYTickNumberHeight; mAxisY.GetTickNumberSize(canvas, NULL, &theYTickNumberHeight); mBack.mMargin.mBottom += theYTickNumberHeight/2; } else { int theYTickNumberWidth; mAxisY.GetTickNumberSize(canvas, &theYTickNumberWidth, NULL); mBack.mMargin.mBottom += theYTickNumberWidth/2; } } } } if (mBack.mMarginAuto.mRight) { mBack.mMargin.mRight = 0; if (mAxisX.mShow) { if (mAxisX.mShowArrow && !mAxisX.mReverse) mBack.mMargin.mRight += mAxisX.mTick.mMinorSize + 2 + 5; // size of the arrow if (mAxisX.mTick.mShowNumber) { if (mAxisX.mTick.mRotateNumber) { int theXTickNumberHeight; mAxisX.GetTickNumberSize(canvas, NULL, &theXTickNumberHeight); mBack.mMargin.mRight += theXTickNumberHeight/2; } else { int theXTickNumberWidth; mAxisX.GetTickNumberSize(canvas, &theXTickNumberWidth, NULL); mBack.mMargin.mRight += theXTickNumberWidth/2; } } } } if (mBack.mMarginAuto.mLeft) { mBack.mMargin.mLeft = 0; if (mAxisY.mShow && !mAxisY.mCrossOrigin) { mBack.mMargin.mLeft += mAxisY.mTick.mMajorSize; if (mAxisY.mTick.mShowNumber) { if (mAxisY.mTick.mRotateNumber) { int theYTickNumberHeight; mAxisY.GetTickNumberSize(canvas, NULL, &theYTickNumberHeight); mBack.mMargin.mLeft += theYTickNumberHeight; } else { int theYTickNumberWidth; mAxisY.GetTickNumberSize(canvas, &theYTickNumberWidth, NULL); mBack.mMargin.mLeft += theYTickNumberWidth; } } if (mAxisY.GetLabel()) { int theYFontHeight; SetFont(canvas, mAxisY.mFontStyle, mAxisY.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theYFontHeight, NULL, NULL); mBack.mMargin.mLeft += theYFontHeight + theYFontHeight / 10; } } if (mAxisX.mShow) { if (mAxisX.mShowArrow && mAxisX.mReverse) mBack.mMargin.mLeft += mAxisX.mTick.mMinorSize + 2 + 5; // size of the arrow if (mAxisX.mTick.mShowNumber) { if (mAxisX.mTick.mRotateNumber) { int theXTickNumberHeight; mAxisX.GetTickNumberSize(canvas, NULL, &theXTickNumberHeight); mBack.mMargin.mLeft += theXTickNumberHeight / 2; } else { int theXTickNumberWidth; mAxisX.GetTickNumberSize(canvas, &theXTickNumberWidth, NULL); mBack.mMargin.mLeft += theXTickNumberWidth / 2; } } } } }
bool iupPlot::DrawSampleColorLegend(iupPlotDataSet *dataset, const iupPlotRect &inRect, cdCanvas* canvas, iupPlotRect &ioPos) const { if (mLegend.mShow) { int theFontHeight; SetFont(canvas, mLegend.mFontStyle, mLegend.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theFontHeight, NULL, NULL); int theMargin = theFontHeight / 2; if (mLegend.mPosition == IUP_PLOT_BOTTOMCENTER) theMargin = 0; int theCount = dataset->GetCount(); int theTotalHeight = theCount*theFontHeight + 2 * theMargin; int theLineSpace = theFontHeight / 2 + 3; int theWidth, theMaxWidth = 0; for (int i = 0; i < theCount; i++) { cdCanvasGetTextSize(canvas, ((iupPlotDataString *)dataset->GetDataX())->GetSampleString(i), &theWidth, NULL); theWidth += theLineSpace; if (theWidth > theMaxWidth) theMaxWidth = theWidth; } if (theMaxWidth == 0) return false; theMaxWidth += 2 * theMargin; if (mLegend.mPosition != IUP_PLOT_XY) { int theScreenX = inRect.mX; int theScreenY = inRect.mY; switch (mLegend.mPosition) { case IUP_PLOT_TOPLEFT: theScreenX += 2; theScreenY += inRect.mHeight - theTotalHeight - 2; break; case IUP_PLOT_BOTTOMLEFT: theScreenX += 2; theScreenY += 2; break; case IUP_PLOT_BOTTOMRIGHT: theScreenX += inRect.mWidth - theMaxWidth - 2; theScreenY += 2; break; case IUP_PLOT_BOTTOMCENTER: theScreenX += (inRect.mWidth - theMaxWidth) / 2; theScreenY = theFontHeight / 4; break; default: // IUP_PLOT_TOPRIGHT theScreenX += inRect.mWidth - theMaxWidth - 2; theScreenY += inRect.mHeight - theTotalHeight - 2; break; } ioPos.mX = theScreenX; ioPos.mY = theScreenY; } ioPos.mWidth = theMaxWidth; ioPos.mHeight = theTotalHeight; // Clip to the legend box cdCanvasClipArea(canvas, ioPos.mX, ioPos.mX + ioPos.mWidth - 1, ioPos.mY, ioPos.mY + ioPos.mHeight - 1); if (mLegend.mBoxShow) { cdCanvasSetForeground(canvas, mLegend.mBoxBackColor); iPlotDrawBox(canvas, ioPos.mX + 1, ioPos.mY + 1, ioPos.mWidth - 2, ioPos.mHeight - 2); cdCanvasSetForeground(canvas, mLegend.mBoxColor); iPlotSetLine(canvas, mLegend.mBoxLineStyle, mLegend.mBoxLineWidth); iPlotDrawRectI(canvas, ioPos.mX, ioPos.mY, ioPos.mWidth, ioPos.mHeight); } for (int i = 0; i < theCount; i++) { cdCanvasSetForeground(canvas, iPlotGetSampleColorTable(ih, i)); int theLegendX = ioPos.mX + theMargin; int theLegendY = ioPos.mY + (theCount - 1 - i)*theFontHeight + theMargin; int boxSize = theLineSpace - 3; cdCanvasBox(canvas, theLegendX, theLegendX + boxSize, theLegendY, theLegendY + boxSize); iPlotDrawText(canvas, theLegendX + theLineSpace, theLegendY + boxSize / 2, CD_WEST, ((iupPlotDataString *)dataset->GetDataX())->GetSampleString(i)); } } return true; }
bool iupPlot::DrawLegend(const iupPlotRect &inRect, cdCanvas* canvas, iupPlotRect &ioPos) const { if (mLegend.mShow) { int ds; int theFontHeight; SetFont(canvas, mLegend.mFontStyle, mLegend.mFontSize); cdCanvasGetFontDim(canvas, NULL, &theFontHeight, NULL, NULL); int theMargin = theFontHeight / 2; if (mLegend.mPosition == IUP_PLOT_BOTTOMCENTER) theMargin = 0; int theTotalHeight = mDataSetListCount*theFontHeight + 2 * theMargin; int theLineSpace = 20; int theWidth, theMaxWidth = 0; for (ds = 0; ds < mDataSetListCount; ds++) { iupPlotDataSet* dataset = mDataSetList[ds]; cdCanvasGetTextSize(canvas, dataset->GetName(), &theWidth, NULL); if (dataset->mMode == IUP_PLOT_MARK || dataset->mMode == IUP_PLOT_MARKLINE) { if (dataset->mMarkSize + 6 > theLineSpace) theLineSpace = dataset->mMarkSize + 6; } theWidth += theLineSpace; if (theWidth > theMaxWidth) theMaxWidth = theWidth; } if (theMaxWidth == 0) return false; theMaxWidth += 2 * theMargin; if (mLegend.mPosition != IUP_PLOT_XY) { int theScreenX = inRect.mX; int theScreenY = inRect.mY; switch (mLegend.mPosition) { case IUP_PLOT_TOPLEFT: theScreenX += 2; theScreenY += inRect.mHeight - theTotalHeight - 2; break; case IUP_PLOT_BOTTOMLEFT: theScreenX += 2; theScreenY += 2; break; case IUP_PLOT_BOTTOMRIGHT: theScreenX += inRect.mWidth - theMaxWidth - 2; theScreenY += 2; break; case IUP_PLOT_BOTTOMCENTER: theScreenX += (inRect.mWidth - theMaxWidth) / 2; theScreenY = theFontHeight / 4; break; default: // IUP_PLOT_TOPRIGHT theScreenX += inRect.mWidth - theMaxWidth - 2; theScreenY += inRect.mHeight - theTotalHeight - 2; break; } ioPos.mX = theScreenX; ioPos.mY = theScreenY; } ioPos.mWidth = theMaxWidth; ioPos.mHeight = theTotalHeight; // Clip to the legend box cdCanvasClipArea(canvas, ioPos.mX, ioPos.mX + ioPos.mWidth - 1, ioPos.mY, ioPos.mY + ioPos.mHeight - 1); if (mLegend.mBoxShow) { cdCanvasSetForeground(canvas, mLegend.mBoxBackColor); iPlotDrawBox(canvas, ioPos.mX + 1, ioPos.mY + 1, ioPos.mWidth - 2, ioPos.mHeight - 2); cdCanvasSetForeground(canvas, mLegend.mBoxColor); iPlotSetLine(canvas, mLegend.mBoxLineStyle, mLegend.mBoxLineWidth); iPlotDrawRectI(canvas, ioPos.mX, ioPos.mY, ioPos.mWidth, ioPos.mHeight); } for (ds = 0; ds < mDataSetListCount; ds++) { iupPlotDataSet* dataset = mDataSetList[ds]; cdCanvasSetForeground(canvas, dataset->mColor); int theLegendX = ioPos.mX + theMargin; int theLegendY = ioPos.mY + (mDataSetListCount - 1 - ds)*theFontHeight + theMargin; theLegendY += theFontHeight / 2; if (dataset->mMode == IUP_PLOT_MARK || dataset->mMode == IUP_PLOT_MARKLINE) { iPlotSetMark(canvas, dataset->mMarkStyle, dataset->mMarkSize); cdCanvasMark(canvas, theLegendX + (theLineSpace - 3) / 2, theLegendY - theFontHeight / 8); } if (dataset->mMode != IUP_PLOT_MARK) { iPlotSetLine(canvas, dataset->mLineStyle, dataset->mLineWidth); cdCanvasLine(canvas, theLegendX, theLegendY - theFontHeight / 8, theLegendX + theLineSpace - 3, theLegendY - theFontHeight / 8); } iPlotDrawText(canvas, theLegendX + theLineSpace, theLegendY, CD_WEST, dataset->GetName()); } } return true; }
bool iupPlotAxis::DrawY(const iupPlotRect &inRect, cdCanvas* canvas, const iupPlotAxis& inAxisX) const { if (!mShow) return true; cdCanvasSetForeground(canvas, mColor); iPlotSetLine(canvas, CD_CONTINUOUS, mLineWidth); double theScreenX = GetScreenXOriginY(inAxisX); double theScreenY1 = inRect.mY; double theScreenY2 = theScreenY1 + inRect.mHeight; cdfCanvasLine(canvas, theScreenX, theScreenY1, theScreenX, theScreenY2); if (mShowArrow) { if (!mReverse) iPlotDrawArrow(canvas, theScreenX, theScreenY2, 1, 1, mTick.mMinorSize); else iPlotDrawArrow(canvas, theScreenX, theScreenY1, 1, -1, mTick.mMinorSize); } if (mTick.mShow) { if (!mTickIter->Init()) return false; double theY; bool theIsMajorTick; char theFormatString[30]; strcpy(theFormatString, mTick.mFormatString); if (mTick.mShowNumber) SetFont(canvas, mTick.mFontStyle, mTick.mFontSize); while (mTickIter->GetNextTick(theY, theIsMajorTick, theFormatString)) { if (!DrawYTick(theY, theScreenX, theIsMajorTick, theFormatString, canvas)) return false; } theScreenX -= mTick.mMajorSize; // skip major tick if (mTick.mShowNumber) { if (mTick.mRotateNumber) { int theYTickNumberHeight; GetTickNumberSize(canvas, NULL, &theYTickNumberHeight); theScreenX -= theYTickNumberHeight; } else { int theYTickNumberWidth; GetTickNumberSize(canvas, &theYTickNumberWidth, NULL); theScreenX -= theYTickNumberWidth; } } } if (GetLabel()) { SetFont(canvas, mFontStyle, mFontSize); if (mLabelSpacing == -1) { int theYFontHeight; cdCanvasGetFontDim(canvas, NULL, &theYFontHeight, NULL, NULL); theScreenX -= theYFontHeight / 10; // default spacing } else theScreenX -= mLabelSpacing; if (mLabelCentered) { double theScreenY = theScreenY1 + inRect.mHeight / 2; iPlotDrawRotatedText(canvas, theScreenX, theScreenY, 90, CD_SOUTH, GetLabel()); } else { double theScreenY = theScreenY2; iPlotDrawRotatedText(canvas, theScreenX, theScreenY, 90, CD_SOUTH_EAST, GetLabel()); } } return true; }