/* Copyright (c) 2008-2019 Jan W. Krieger () This software is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License (LGPL) for more details. You should have received a copy of the GNU Lesser General Public License (LGPL) along with this program. If not, see . */ #include "jkqtplotter/jkqtpcoordinateaxes.h" #include "jkqtplotter/jkqtpbaseplotter.h" #include "jkqtcommon/jkqtpdrawingtools.h" #include #include #include #include //#undef SHOW_JKQTPLOTTER_DEBUG //#define SHOW_JKQTPLOTTER_DEBUG JKQTPCoordinateAxis::JKQTPCoordinateAxis(JKQTBasePlotter* _parent): QObject(_parent), paramsChanged(true), doUpdateScaling(true), tickLabels(), parent(_parent), axismin(-10), axismax(10), axisabsoultemin(-DBL_MAX/100.), axisabsoultemax(DBL_MAX/100.0), axisStyle(), axisMinWidth(-1), width(20), scale(0), offset(0), inverted(false), tickStart(1), autoAxisSpacing(true), logAxis(false), logAxisBase(10), userTickSpacing(1), userLogTickSpacing(10), tickSpacing(0), tickSpacingLog(10), axisLabel(), axisPrefix(), scaleSign(1) { } JKQTPCoordinateAxis::~JKQTPCoordinateAxis() { } void JKQTPCoordinateAxis::setParent(JKQTBasePlotter* parent) { this->parent=parent; QObject::setParent(parent); } void JKQTPCoordinateAxis::redrawPlot() { //if (paramsChanged) { calcPlotScaling(); parent->redrawPlot(); //} } JKQTMathText* JKQTPCoordinateAxis::getParentMathText() { return parent->getMathText(); } void JKQTPCoordinateAxis::clearAxisTickLabels() { tickLabels.clear(); redrawPlot(); } void JKQTPCoordinateAxis::addAxisTickLabel(double x, const QString& label) { tickLabels.append(qMakePair(x, label)); redrawPlot(); } void JKQTPCoordinateAxis::addAxisTickLabels(const QVector &x, const QStringList &label) { for (int i=0; i &x, const QString *label) { for (int i=0; i0 && res[res.size()-1]=='0') { res=res.left(res.size()-1); } if (res.size()>0 && res[res.size()-1]==loc.decimalPoint()) res=res.left(res.size()-1); } return res; }; break; case JKQTPCALTexponent: { return QString(jkqtp_floattolatexstr(data, past_comma, remove_trail0, belowIsZero, pow(10, -past_comma), pow(10, past_comma+1)).c_str()); }; break; case JKQTPCALTexponentCharacter: { return QString(jkqtp_floattounitstr(data, past_comma, remove_trail0).c_str()); }; break; case JKQTPCALTdate: { QDateTime dt; dt.setMSecsSinceEpoch(uint64_t(data)); return dt.toString(axisStyle.tickDateFormat); }; break; case JKQTPCALTtime: { QDateTime dt; dt.setMSecsSinceEpoch(uint64_t(data)); return dt.toString(axisStyle.tickTimeFormat); }; break; case JKQTPCALTdatetime: { QDateTime dt; dt.setMSecsSinceEpoch(uint64_t(data)); return dt.toString(axisStyle.tickDateTimeFormat); }; break; default: return QString(); break; } /* axisStyle.tickTimeFormat axisStyle.tickDateFormat axisStyle.tickDateTimeFormat **/ return QString(); } QString JKQTPCoordinateAxis::floattolabel(double data, int past_comma) { bool remove_trail0=true; QLocale loc=QLocale::system(); loc.setNumberOptions(QLocale::OmitGroupSeparator); if (axisStyle.labelType==JKQTPCALTdefault) { QString res=loc.toString(data, 'f', past_comma);//QString::number(data, 'f', past_comma); if (remove_trail0 && res.contains(QLocale::system().decimalPoint())) { while (res.size()>0 && res[res.size()-1]=='0') { res=res.left(res.size()-1); } if (res.size()>0 && res[res.size()-1]==loc.decimalPoint()) res=res.left(res.size()-1); } return res; } else if (axisStyle.labelType==JKQTPCALTexponent) return QString(jkqtp_floattolatexstr(data, past_comma, remove_trail0, 1e-300, pow(10, -past_comma), pow(10, past_comma+1)).c_str()); else if (axisStyle.labelType==JKQTPCALTexponentCharacter) return QString(jkqtp_floattounitstr(data, past_comma, remove_trail0).c_str()); return ""; } int JKQTPCoordinateAxis::calcLinearUnitDigits() { if (!axisStyle.autoLabelDigits) return axisStyle.labelDigits; int unitdigits=-1; double minval=tickStart; bool equals=true; /*for (int i=0; i<20; i++) { equals=equals || (floattolabel((minval+static_cast(i)*tickSpacing), unitdigits)== floattolabel((minval+static_cast(i+1)*tickSpacing), unitdigits)); }*/ while ((unitdigits<20) && equals) { unitdigits++; equals=false; for (int i=-10; i<10; i++) { QString l1=floattolabel((minval+static_cast(i)*tickSpacing), unitdigits+2); QString l2=floattolabel((minval+static_cast(i+1.0)*tickSpacing), unitdigits+2); //qDebug()<<"unitdigits="<axismax) { std::swap(axismin, axismax); } else if (axismax==axismin) { axismax=axismin+1.0; } if (isLogAxis()) { if (axismin<0) { if (axismax>0) axismin=axismax/(logAxisBase*logAxisBase); else axismin=1e-5; } if (axismax<=axismin) axismax=axismin*logAxisBase*logAxisBase; //if (axismax<0) axismax=pow(10.0, ceil(log10(axismax-axismin)+1.0)); if (axismin<=0) axismin=1e-5; if (axismax<=0) axismax=axismin+pow(10.0, static_cast(log10(axismin))); if (axismax(log10(axismin))); } } if (axismin>axismax) { std::swap(axismin, axismax); } else if (axismax==axismin) { axismax=axismin+1.0; } // this is the x- and y-range spanned by the plot width=fabs(axismax-axismin); //qDebug()<<"calcPlotScaling():\n"; //qDebug()<<" width="<objectName()<<": inverted = "<objectName()<<": plotOffset = "<objectName()<<": plotWidth = "<0) { offset=plotOffset-log(axismin)/log(logAxisBase)*scale; } else { offset=plotOffset+log(axismax)/log(logAxisBase)*scale; } } else { scale=getParentPlotWidth()/width; if (scaleSign>0) { offset=plotOffset-axismin*scale; } else { offset=plotOffset+axismax*scale; } } #ifdef SHOW_JKQTPLOTTER_DEBUG //qDebug()<objectName()<<": offset = "<objectName()<<": scale = "<objectName()<<": scaleSign = "<paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::loadCurrentAxisStyle(const QSettings &settings, const QString &group) { axisStyle.loadSettings(settings, group); this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::saveCurrentAxisStyle(QSettings &settings, const QString &group) const { axisStyle.saveSettings(settings, group); } void JKQTPCoordinateAxis::setRange(double aamin, double aamax) { double oldamin=axismin; double oldamax=axismax; double amin=aamin; double amax=aamax; if (axisMinWidth>0 && fabs(amax-amin)axisabsoultemax) axismax=axisabsoultemax; if (axismin>axismax) { axismin=amax; axismax=amin; } if (isLogAxis()) { if (axismin<=0) axismin=1e-306; if (axismax<=0) axismax=1e-306; if (fabs(axismin-axismax)<1e-306) { axismax=10; axismin=0.1; } } if (axisMinWidth>0 && fabs(axismax-axismin)tickSpacing = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setAxisMinWidth(double __value) { this->axisMinWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setAutoAxisSpacing(bool __value) { this->autoAxisSpacing = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickLabelsEnabled(bool __value) { this->axisStyle.minorTickLabelsEnabled = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLogAxis(bool __value) { this->logAxis = __value; this->paramsChanged=true; if (this->isLogAxis()) { if (axismin<0) axismin=pow(10.0, floor(log(axismax-axismin)/log(10.0)-1.0)); if (axismax<0) axismax=pow(10.0, floor(log(axismax-axismin)/log(10.0)+1.0)); } redrawPlot(); } void JKQTPCoordinateAxis::setLogAxisBase(double __value) { this->logAxisBase = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setUserTickSpacing(double __value) { this->userTickSpacing = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setUserLogTickSpacing(double __value) { this->userLogTickSpacing = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLabelType(JKQTPCALabelType __value) { this->axisStyle.labelType = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickMode(JKQTPLabelTickMode __value) { this->axisStyle.tickMode = __value; this->paramsChanged=true; setLogAxis(this->logAxis); } void JKQTPCoordinateAxis::setTickMode(int __value) { setTickMode(JKQTPLabelTickMode(__value)); } void JKQTPCoordinateAxis::setAxisLabel(const QString& __value) { this->axisLabel = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLabelPosition(JKQTPLabelPosition __value) { this->axisStyle.labelPosition = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLabelFontSize(double __value) { this->axisStyle.labelFontSize = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickTimeFormat(const QString& __value) { this->axisStyle.tickTimeFormat = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickDateFormat(const QString& __value) { this->axisStyle.tickDateFormat = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickDateTimeFormat(const QString& __value) { this->axisStyle.tickDateTimeFormat = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickLabelFontSize(double __value) { this->axisStyle.tickLabelFontSize = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickLabelFontSize(double __value) { this->axisStyle.minorTickLabelFontSize = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickLabelFullNumber(bool __value) { this->axisStyle.minorTickLabelFullNumber = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinTicks(unsigned int __value) { this->axisStyle.minTicks = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTicks(unsigned int __value) { this->axisStyle.minorTicks = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTicks(int __value) { this->axisStyle.minorTicks = qMax(int(0), __value); this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickOutsideLength(double __value) { this->axisStyle.tickOutsideLength = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickOutsideLength(double __value) { this->axisStyle.minorTickOutsideLength = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickInsideLength(double __value) { this->axisStyle.tickInsideLength = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickInsideLength(double __value) { this->axisStyle.minorTickInsideLength = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setAxisColor(const QColor& __value) { this->axisStyle.axisColor = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setShowZeroAxis(bool __value) { this->axisStyle.showZeroAxis = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setInverted(bool __value) { this->inverted = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setGridColor(const QColor& __value) { this->axisStyle.gridColor = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorGridColor(const QColor& __value) { this->axisStyle.minorGridColor = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setGridWidth(double __value) { this->axisStyle.gridWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setGridStyle(Qt::PenStyle __value) { this->axisStyle.gridStyle = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorGridWidth(double __value) { this->axisStyle.minorGridWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorGridStyle(Qt::PenStyle __value) { this->axisStyle.minorGridStyle = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setDrawMode1(JKQTPCADrawMode __value) { this->axisStyle.drawMode1 = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setDrawMode2(JKQTPCADrawMode __value) { this->axisStyle.drawMode2 = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setMinorTickWidth(double __value) { this->axisStyle.minorTickWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickWidth(double __value) { this->axisStyle.tickWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLineWidth(double __value) { this->axisStyle.lineWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLineWidthZeroAxis(double __value) { this->axisStyle.lineWidthZeroAxis = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickLabelDistance(double __value) { this->axisStyle.tickLabelDistance = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLabelDistance(double __value) { this->axisStyle.labelDistance = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setLabelDigits(int __value) { this->axisStyle.labelDigits = __value; this->paramsChanged=true; this->axisStyle.autoLabelDigits=false; redrawPlot(); } void JKQTPCoordinateAxis::setDrawGrid(bool __value) { this->axisStyle.drawGrid = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setDrawMinorGrid(bool __value) { this->axisStyle.drawMinorGrid = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setTickLabelAngle(double __value) { this->axisStyle.tickLabelAngle = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPCoordinateAxis::setAbsoluteRange(double amin, double amax) { axisabsoultemin=amin; axisabsoultemax=amax; if (axisabsoultemin>axisabsoultemax) { axisabsoultemin=amax; axisabsoultemax=amin; } if (axisabsoultemin==axisabsoultemax) { axisabsoultemax=axisabsoultemin+1; } setRange(axismin, axismax); /*paramsChanged=true; calcPlotScaling(); redrawPlot();*/ } double JKQTPCoordinateAxis::getNextLabelDistance(double x) { if (axisStyle.tickMode==JKQTPLTMLinOrPower) { if (logAxis) { return x*tickSpacingLog; } else { return tickSpacing; } } else if (axisStyle.tickMode==JKQTPLTMLin) { return tickSpacing; } else if (axisStyle.tickMode==JKQTPLTMPower) { return x*tickSpacingLog; } return 0; } bool JKQTPCoordinateAxis::getNextLabel(double& x, QString& label, bool init) { //qDebug()<<"start JKQTPCoordinateAxis::getNextLabel("<=axismin && x<=axismax) { label=floattolabel(x); } return (x<=axismax); } else { if (init) { if (tickLabels.size()>0) { x=tickLabels[0].first; label=tickLabels[0].second; } return (tickLabels.size()>0); } else { for (int i=0; i=axismin && x<=axismax) { label=tickLabels[i+1].second; x=tickLabels[i+1].first; return true; } else { return false; } } } } } return false; } QSizeF JKQTPCoordinateAxis::getMaxTickLabelSize(JKQTPEnhancedPainter& painter, double* ascent, double* descent) { double w=0, h=0, a=0; calcPlotScaling(); double x=tickStart; QString label=""; getNextLabel(x, label, true); QFont f; f.setFamily(getParent()->getCurrentPlotterStyle().defaultFontName); f.setPointSizeF(this->axisStyle.tickLabelFontSize*parent->getFontSizeMultiplier()); QFontMetricsF fm(f); bool first=true; int cnt=0; while (getNextLabel(x, label, first) && cnt<50) { double width, ascent, descent, strikeoutPos; parent->getTextSizeDetail(f, label, painter, width, ascent, descent, strikeoutPos); if (width>w) w=width; if (ascent+descent>h) h=ascent+descent; if (ascent>a) a=ascent; first=false; cnt++; } //qDebug()<<"getMaxTickLabelSize() = ["<getCurrentPlotterStyle().yAxisStyle; } else { axisStyle=JKQTPGetSystemDefaultBaseStyle().yAxisStyle; } } double JKQTPVerticalAxis::getParentPlotWidth() const { return parent->getPlotHeight(); } double JKQTPVerticalAxis::getParentPlotOffset() const { return parent->getInternalPlotBorderTop(); } QSizeF JKQTPVerticalAxis::getSize1(JKQTPEnhancedPainter& painter) { if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0); double ptwidth=axisStyle.axisLineOffset; double labwidth=0; if (JKQTPCADrawModeHasTicks(axisStyle.drawMode1)) ptwidth+=axisStyle.tickOutsideLength; if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { ptwidth+=axisStyle.tickLabelDistance; // find out the maximum width over all visible plot labels labwidth+=getMaxTickLabelSize(painter).width(); } if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { ptwidth+=axisStyle.labelDistance; // find out size of axis label labwidth+=parent->getTextSizeSize(getParent()->getCurrentPlotterStyle().defaultFontName, axisStyle.labelFontSize*parent->getFontSizeMultiplier(), axisLabel, painter).height(); } return QSizeF(parent->pt2px(painter, ptwidth)+labwidth, getParentPlotWidth()); } QSizeF JKQTPVerticalAxis::getSize2(JKQTPEnhancedPainter& painter) { if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0); double ptwidth=axisStyle.axisLineOffset; double labwidth=0; if (JKQTPCADrawModeHasTicks(axisStyle.drawMode2)) ptwidth+=axisStyle.tickOutsideLength; if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { ptwidth+=axisStyle.tickLabelDistance; // find out the maximum width over all visible plot labels labwidth+=getMaxTickLabelSize(painter).width(); } if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { ptwidth+=axisStyle.labelDistance; // find out size of axis label labwidth+=parent->getTextSizeSize(getParent()->getCurrentPlotterStyle().defaultFontName, axisStyle.labelFontSize*parent->getFontSizeMultiplier(), axisLabel, painter).height(); } return QSizeF(parent->pt2px(painter, ptwidth)+labwidth, getParentPlotWidth()); } double JKQTPVerticalAxis::getParentOtheraxisOffset() const { return parent->x2p(parent->getXMin()); } double JKQTPVerticalAxis::getParentOtheraxisWidth() const { return fabs(parent->x2p(parent->getXMax())-parent->x2p(parent->getXMin())); } bool JKQTPVerticalAxis::getParentOtheraxisInverted() const { return parent->getXAxis()->getInverted(); } void JKQTPVerticalAxis::drawGrids(JKQTPEnhancedPainter& painter) { //qDebug()<<" start JKQTPVerticalAxis::drawGrids("; painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen pg=painter.pen(); pg.setColor(axisStyle.gridColor); pg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getLineWidthMultiplier()))); pg.setStyle(axisStyle.gridStyle); QPen pmg=painter.pen(); pmg.setColor(axisStyle.minorGridColor); pmg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); pmg.setStyle(axisStyle.minorGridStyle); //double top=x2p(axismax); //double bottom=x2p(axismin); double left=0; double right=0; if (getParentOtheraxisInverted()) { left=getParentOtheraxisOffset()-getParentOtheraxisWidth();//; right=getParentOtheraxisOffset();//; } else { left=getParentOtheraxisOffset();//; right=getParentOtheraxisOffset()+getParentOtheraxisWidth();//; } double x=tickStart; QString label=""; bool first=true; // loop through all labels, as they are at the major ticks, do not draw more than 200 labels (prevent hang ups) int cnt=0; QVector lines_pg; QVector lines_pmg; while (getNextLabel(x, label, first) && (cnt<200)) { double w=getNextLabelDistance(x); double mtdist=w/static_cast(axisStyle.minorTicks+1); double xx=x2p(x); //qDebug()<<" tick @ x="<axismin) && (fabs(left-right)>0)) { QLineF l(left, xx, right, xx); if (l.length()>0) lines_pg.append(l);//painter.drawLine(l); } //qDebug()<<" 2"; //painter.setPen(pmg); //qDebug()<<" 3"; if ((tickLabels.size()<=0) && axisStyle.drawMinorGrid && (axisStyle.minorTicks>0) && (fabs(right-left)>0)) { //qDebug()<<" 3.1"; double mx=x+mtdist; //qDebug()<<" 3.2"; for (int i=0; i(axisStyle.minorTicks); i++) { //qDebug()<<" 3.2.1"; double mxx=x2p(mx); //qDebug()<<" 3.2.2"; if ((mxaxismin) && (fabs(right-left)>0)) { QLineF l(left, mxx, right, mxx); if (l.length()>0) lines_pmg.append(l);//painter.drawLine(l); } //qDebug()<<" 3.2.3"; mx=mx+mtdist; //qDebug()<<" 3.2.4"; } } first=false; cnt++; } painter.setPen(pg); painter.drawLines(lines_pg); painter.setPen(pmg); painter.drawLines(lines_pmg); //qDebug()<<" end JKQTPVerticalAxis::drawGrids("; } void JKQTPVerticalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, const QString& label, double fontSize) { getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontColor(axisStyle.axisColor); getParentMathText()->parse(label); double width, ascent, descent, strikeoutPos; getParentMathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos); if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { double lx=xx-parent->pt2px(painter, axisStyle.minorTickOutsideLength+axisStyle.tickLabelDistance)-width; if (axisStyle.tickLabelAngle==90) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(lx+width-1.25*strikeoutPos, yy-width/2.0); painter.rotate(axisStyle.tickLabelAngle); getParentMathText()->draw(painter, 0,0); } else if (axisStyle.tickLabelAngle==-90) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(lx+width-0.25*strikeoutPos, yy+width/2.0); painter.rotate(axisStyle.tickLabelAngle); getParentMathText()->draw(painter, 0,0); } else if (axisStyle.tickLabelAngle!=0) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); if (axisStyle.tickLabelAngle>0) { painter.translate(lx-strikeoutPos+(width)*(1.0-cos(fabs(axisStyle.tickLabelAngle)/180.0*JKQTPSTATISTICS_PI)), yy+strikeoutPos-width*sin(fabs(axisStyle.tickLabelAngle)/180.0*JKQTPSTATISTICS_PI)); painter.rotate(axisStyle.tickLabelAngle); } else { painter.translate(lx+strikeoutPos+(width-strikeoutPos)*(1.0-cos(fabs(axisStyle.tickLabelAngle)/180.0*JKQTPSTATISTICS_PI)), yy+strikeoutPos+width*sin(fabs(axisStyle.tickLabelAngle)/180.0*JKQTPSTATISTICS_PI)); painter.rotate(axisStyle.tickLabelAngle); } getParentMathText()->draw(painter, 0,0); } else { getParentMathText()->draw(painter, lx, yy+strikeoutPos); } } } void JKQTPVerticalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, const QString &label, double fontSize) { getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontColor(axisStyle.axisColor); getParentMathText()->parse(label); double width, ascent, descent, strikeoutPos; getParentMathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos); if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { double lx=xx+parent->pt2px(painter, axisStyle.tickOutsideLength+axisStyle.tickLabelDistance); if (axisStyle.tickLabelAngle==90) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(lx+descent, yy-width/2.0); painter.rotate(axisStyle.tickLabelAngle); getParentMathText()->draw(painter, 0,0); } else if (axisStyle.tickLabelAngle==-90) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(lx+ascent, yy+width/2.0); painter.rotate(axisStyle.tickLabelAngle); getParentMathText()->draw(painter, 0,0); } else if (axisStyle.tickLabelAngle!=0) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); double shiftx=0; if (axisStyle.tickLabelAngle>0) { shiftx=strikeoutPos*sin(fabs(axisStyle.tickLabelAngle)/180.0*JKQTPSTATISTICS_PI); } else { } painter.translate(lx+shiftx, yy+strikeoutPos); painter.rotate(-axisStyle.tickLabelAngle); getParentMathText()->draw(painter, 0,0); } else { getParentMathText()->draw(painter, lx, yy+strikeoutPos); } } } void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes()").arg(objectName())); #endif // make shure all parameters are calculated correctly calcPlotScaling(); // determine pixel coordinates of important positions double top=x2p(axismax); double bottom=x2p(axismin); double left=0; double right=0; if (inverted) { qSwap(top, bottom); } if (getParentOtheraxisInverted()) { left=getParentOtheraxisOffset()-getParentOtheraxisWidth();//; right=getParentOtheraxisOffset();//; } else { left=getParentOtheraxisOffset();//; right=getParentOtheraxisOffset()+getParentOtheraxisWidth();//; } // move axes outside plot rectangle, if required left-=parent->pt2px(painter, axisStyle.axisLineOffset); right+=parent->pt2px(painter, axisStyle.axisLineOffset); //qDebug()<<"JKQTPVerticalAxis:"; //qDebug()<<" left="<pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); pmain.setStyle(Qt::SolidLine); QPen ptick=pmain; ptick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); QPen pmtick=ptick; pmtick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); getParentMathText()->setFontSize(this->axisStyle.tickLabelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontColor(axisStyle.axisColor); painter.setPen(pmain); // plot thick axis at y==0 if (axisStyle.showZeroAxis && (0>axismin) && (0pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); pmain1.setColor(axisStyle.colorZeroAxis); pmain1.setStyle(axisStyle.styleZeroAxis); painter.setPen(pmain1); QLineF l(left-parent->pt2px(painter, axisStyle.tickOutsideLength), x2p(0), right+parent->pt2px(painter, axisStyle.tickOutsideLength), x2p(0)); painter.drawLine(l); painter.setPen(pmain); } // draw thick axis lines, left and/or right if ( JKQTPCADrawModeHasLine(axisStyle.drawMode1)) { QLineF l(left, x2p(axismin), left, x2p(axismax)); painter.drawLine(l); } if (JKQTPCADrawModeHasLine(axisStyle.drawMode2)) { QLineF l(right, x2p(axismin), right, x2p(axismax)); painter.drawLine(l); } // plot minor and major ticks + tick labels QSizeF labelMax=getMaxTickLabelSize(painter); double x=tickStart; QString label=""; bool first=true; // loop through all labels, as they are at the major ticks int cnt=0; QVector lines_ptick, lines_ptick2; QVector lines_pmtick, lines_pmtick2; { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): calcLabels").arg(objectName())); #endif while (getNextLabel(x, label, first) && cnt<200) { double mtdist=getNextLabelDistance(x)/static_cast(axisStyle.minorTicks+1); double xleft=-1000000; double xx=x2p(x); //qDebug()<<" tick @ x="< "<=axismin) { QLineF l(xleft=left-parent->pt2px(painter, axisStyle.minorTickOutsideLength), mxx, left+parent->pt2px(painter, axisStyle.minorTickInsideLength), mxx); if (l.length()>0) lines_pmtick.append(l);//painter.drawLine(l); double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase))); if (axisStyle.minorTickLabelsEnabled&&JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { if (axisStyle.minorTickLabelFullNumber) val=mx; QString minorlabel=floattolabel(val); drawTickLabel1(painter, left, mxx, minorlabel, axisStyle.minorTickLabelFontSize); //drawTickLabel2(painter, right, xx, minorlabel, axisStyle.minorTickLabelFontSize); } } mx=mx+mtdist; } } } if (JKQTPCADrawModeHasTicks(axisStyle.drawMode2)||JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { //painter.setPen(ptick); if (x<=axismax && x>=axismin) { QLineF l(right-parent->pt2px(painter, axisStyle.tickInsideLength), xx, right+parent->pt2px(painter, axisStyle.tickOutsideLength), xx); if (l.length()>0) lines_ptick2.append(l);//painter.drawLine(l); } //painter.setPen(pmtick); if ((tickLabels.size()<=0) && (axisStyle.minorTicks>0)) { double mx=x+mtdist; int minTickCnt=axisStyle.minorTicks; if (isLogAxis()) { if (mtdist>x) { mx=mtdist; } else { minTickCnt--; mx=2.0*mtdist; } } for (int i=0; i=axismin) { QLineF l(right-parent->pt2px(painter, axisStyle.minorTickInsideLength), mxx, xleft=(right+parent->pt2px(painter, axisStyle.minorTickOutsideLength)), mxx); if (l.length()>0) lines_pmtick2.append(l);//painter.drawLine(l); double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase))); if (axisStyle.minorTickLabelsEnabled) { if (axisStyle.minorTickLabelFullNumber&&JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) val=mx; QString minorlabel=floattolabel(val); //drawTickLabel1(painter, left, xx, minorlabel, axisStyle.minorTickLabelFontSize); drawTickLabel2(painter, xleft, mxx, minorlabel, axisStyle.minorTickLabelFontSize); } } mx=mx+mtdist; } } } if ((label!="") && (x<=axismax && x>=axismin)) { if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) drawTickLabel1(painter, left, xx, label, this->axisStyle.tickLabelFontSize); if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) drawTickLabel2(painter, right, xx, label, this->axisStyle.tickLabelFontSize); } first=false; cnt++; } } { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): drawLines").arg(objectName())); #endif painter.setPen(ptick); painter.drawLines(lines_ptick); painter.drawLines(lines_ptick2); painter.setPen(pmtick); painter.drawLines(lines_pmtick); painter.drawLines(lines_pmtick2); } // plot axis label if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode1)) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel1").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->parse(axisLabel); double width, ascent, descent, strikeoutPos; getParentMathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos); QRectF rect(0,0, getParentPlotWidth(), ascent+descent);//plotBorderLeft-30); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(QPointF(left-parent->pt2px(painter, axisStyle.tickOutsideLength+axisStyle.tickLabelDistance+axisStyle.labelDistance)-descent-labelMax.width()-labelMax.height(), bottom)); painter.rotate(-90); //JKQTPEnhancedPainter::RenderHints h=painter.renderHints(); //painter.drawRect(rect); //painter.drawEllipse(-4, -4, 8, 8); switch(axisStyle.labelPosition) { case JKQTPLabelMax: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect); break; case JKQTPLabelMin: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect); break; case JKQTPLabelCenter: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect); break; } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("magenta"); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth/2.0); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); painter.drawRect(rect); } painter.resetTransform(); } if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode2)) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes(): axisLabel2").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->parse(axisLabel); QRectF rect(0,0, getParentPlotWidth(), getParentMathText()->getSize(painter).height());//plotBorderLeft-30); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(QPointF(right+parent->pt2px(painter, axisStyle.tickOutsideLength+axisStyle.tickLabelDistance+axisStyle.labelDistance)+labelMax.width(), bottom)); painter.rotate(-90); //JKQTPEnhancedPainter::RenderHints h=painter.renderHints(); //painter.drawRect(rect); //painter.drawEllipse(-4, -4, 8, 8); switch(axisStyle.labelPosition) { case JKQTPLabelMax: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect); break; case JKQTPLabelMin: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect); break; case JKQTPLabelCenter: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect); break; } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("magenta"); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth/2.0); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); painter.drawRect(rect); } //painter.resetTransform(); } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("cyan"); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); QSizeF s1, s2; s1=getSize1(painter); s2=getSize2(painter); painter.drawRect(QRectF(QPointF(left-s1.width(), top), s1)); painter.drawRect(QRectF(QPointF(right, top), s2)); } //qDebug()<<" end JKQTPVerticalAxis::drawAxes("; } JKQTPVerticalIndependentAxis::JKQTPVerticalIndependentAxis(double _axisOffset, double _axisWidth, double _otherAxisOffset, double _otherAxisWidth, JKQTBasePlotter* parent): JKQTPVerticalAxis(parent), axisOffset(_axisOffset), axisWidth(_axisWidth), otherAxisWidth(_otherAxisOffset), otherAxisOffset(_otherAxisWidth), otherAxisInverted(false) { if (parent) { axisStyle=parent->getCurrentPlotterStyle().rightColorbarAxisStyle; } else { axisStyle=JKQTPGetSystemDefaultBaseStyle().rightColorbarAxisStyle; } } void JKQTPVerticalIndependentAxis::setAxisOffset(double __value) { this->axisOffset = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPVerticalIndependentAxis::setAxisWidth(double __value) { this->axisWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPVerticalIndependentAxis::setOtherAxisOffset(double __value) { this->otherAxisOffset = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPVerticalIndependentAxis::setOtherAxisWidth(double __value) { this->otherAxisWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPVerticalIndependentAxis::setOtherAxisInverted(bool __value) { this->otherAxisInverted = __value; this->paramsChanged=true; redrawPlot(); } double JKQTPVerticalIndependentAxis::getParentPlotWidth() const { return axisWidth; } double JKQTPVerticalIndependentAxis::getParentPlotOffset() const { return axisOffset; } double JKQTPVerticalIndependentAxis::getParentOtheraxisWidth() const { return otherAxisWidth; } bool JKQTPVerticalIndependentAxis::getParentOtheraxisInverted() const { return otherAxisInverted; } double JKQTPVerticalIndependentAxis::getParentOtheraxisOffset() const { return otherAxisOffset; } JKQTPHorizontalAxis::JKQTPHorizontalAxis(JKQTBasePlotter* parent): JKQTPCoordinateAxis(parent) { //axisPrefix="xaxis_"; scaleSign=1; if (parent) { axisStyle=parent->getCurrentPlotterStyle().xAxisStyle; } else { axisStyle=JKQTPGetSystemDefaultBaseStyle().xAxisStyle; } } double JKQTPHorizontalAxis::getParentPlotWidth() const { return parent->getPlotWidth(); } double JKQTPHorizontalAxis::getParentPlotOffset() const { return parent->getInternalPlotBorderLeft(); } QSizeF JKQTPHorizontalAxis::getSize1(JKQTPEnhancedPainter& painter) { if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0); double ptwidth=axisStyle.axisLineOffset; double labwidth=0; if (JKQTPCADrawModeHasTicks(axisStyle.drawMode1)) ptwidth+=axisStyle.tickOutsideLength; if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { ptwidth+=axisStyle.tickLabelDistance; // find out the maximum width over all visible plot labels labwidth+=getMaxTickLabelSize(painter).height(); } if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) { ptwidth+=axisStyle.labelDistance; // find out size of axis label labwidth+=parent->getTextSizeSize(getParent()->getCurrentPlotterStyle().defaultFontName, axisStyle.labelFontSize*parent->getFontSizeMultiplier(), axisLabel, painter).height(); } return QSizeF(getParentPlotWidth(), parent->pt2px(painter, ptwidth)+labwidth); } QSizeF JKQTPHorizontalAxis::getSize2(JKQTPEnhancedPainter& painter) { if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0); double ptwidth=axisStyle.axisLineOffset; double labwidth=0; if (JKQTPCADrawModeHasTicks(axisStyle.drawMode2)) ptwidth+=axisStyle.tickOutsideLength; if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { ptwidth+=axisStyle.tickLabelDistance; // find out the maximum width over all visible plot labels labwidth+=getMaxTickLabelSize(painter).height(); } if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) { ptwidth+=axisStyle.labelDistance; // find out size of axis label labwidth+=parent->getTextSizeSize(getParent()->getCurrentPlotterStyle().defaultFontName, axisStyle.labelFontSize*parent->getFontSizeMultiplier(), axisLabel, painter).height(); } return QSizeF(getParentPlotWidth(), parent->pt2px(painter, ptwidth)+labwidth); } double JKQTPHorizontalAxis::getParentOtheraxisOffset() const { return parent->y2p(parent->getYMax()); } double JKQTPHorizontalAxis::getParentOtheraxisWidth() const { return fabs(parent->y2p(parent->getYMax())-parent->y2p(parent->getYMin())); } bool JKQTPHorizontalAxis::getParentOtheraxisInverted() const { return parent->getYAxis()->getInverted(); } void JKQTPHorizontalAxis::drawGrids(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); //double right=x2p(axismax); //double left=x2p(axismin); double bottom=0; double top=0; if (getParentOtheraxisInverted()) { top=getParentOtheraxisOffset()-getParentOtheraxisWidth();//; bottom=getParentOtheraxisOffset();//; } else { top=getParentOtheraxisOffset();//; bottom=getParentOtheraxisOffset()+getParentOtheraxisWidth();//; } QPen pg=painter.pen(); pg.setColor(axisStyle.gridColor); pg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.gridWidth*parent->getFontSizeMultiplier()))); pg.setStyle(axisStyle.gridStyle); QPen pmg=painter.pen(); pmg.setColor(axisStyle.minorGridColor); pmg.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorGridWidth*parent->getLineWidthMultiplier()))); pmg.setStyle(axisStyle.minorGridStyle); double x=tickStart; QString label=""; bool first=true; // loop through all labels, as they are at the major ticks int cnt=0; QVector lines_pg; QVector lines_pmg; while (getNextLabel(x, label, first) && cnt<200) { double mtdist=getNextLabelDistance(x)/static_cast(axisStyle.minorTicks+1); double xx=x2p(x); //qDebug()<<" tick @ x="<pt2px(painter, axisStyle.axisLineOffset); bottom+=parent->pt2px(painter, axisStyle.axisLineOffset); //qDebug()<<" left="<pt2px(painter, axisStyle.lineWidth*parent->getLineWidthMultiplier()))); pmain.setStyle(Qt::SolidLine); QPen ptick=pmain; ptick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.tickWidth*parent->getLineWidthMultiplier()))); QPen pmtick=ptick; pmtick.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, axisStyle.minorTickWidth*parent->getLineWidthMultiplier()))); getParentMathText()->setFontSize(this->axisStyle.tickLabelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontColor(axisStyle.axisColor); painter.setPen(pmain); // plot thick axis at y==0 if (axisStyle.showZeroAxis && (0>axismin) && (0pt2px(painter, axisStyle.lineWidthZeroAxis*parent->getLineWidthMultiplier()))); pmain1.setColor(axisStyle.colorZeroAxis); pmain1.setStyle(axisStyle.styleZeroAxis); painter.setPen(pmain1); QLineF l(x2p(0), bottom+parent->pt2px(painter, axisStyle.tickOutsideLength), x2p(0), top-parent->pt2px(painter, axisStyle.tickOutsideLength)); painter.drawLine(l); painter.setPen(pmain); } // draw thick axis lines, left and/or right if (JKQTPCADrawModeHasLine(axisStyle.drawMode1)) { QLineF l(x2p(axismin), bottom, x2p(axismax), bottom); painter.drawLine(l); } if (JKQTPCADrawModeHasLine(axisStyle.drawMode2)) { QLineF l(x2p(axismin), top, x2p(axismax), top); painter.drawLine(l); } // plot minor and major ticks + tick labels double ascentMax, descentMax; QSizeF labelMax=getMaxTickLabelSize(painter, &ascentMax, &descentMax); double x=tickStart; QString label=""; bool first=true; // loop through all labels, as they are at the major ticks int cnt=0; QVector lines_ptick, lines_ptick2; QVector lines_pmtick, lines_pmtick2; { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): calcLabels").arg(objectName())); #endif while (getNextLabel(x, label, first) && cnt<200) { double mtdist=getNextLabelDistance(x)/static_cast(axisStyle.minorTicks+1); double xleft=-1000000; double xx=x2p(x); //qDebug()<<" tick @ x="<=axismin)) { if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode1)) drawTickLabel1(painter, xx, bottom, label, this->axisStyle.tickLabelFontSize, ascentMax, descentMax); if (JKQTPCADrawModeHasTickLabels(axisStyle.drawMode2)) drawTickLabel2(painter, xx, top, label, this->axisStyle.tickLabelFontSize, ascentMax, descentMax); } first=false; cnt++; } } { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): drawLines").arg(objectName())); #endif painter.setPen(ptick); painter.drawLines(lines_ptick); painter.drawLines(lines_ptick2); painter.setPen(pmtick); painter.drawLines(lines_pmtick); painter.drawLines(lines_pmtick2); } // plot axis label if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode1)) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel1").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->parse(axisLabel); double width, ascent, descent, strikeoutPos; getParentMathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos); QRectF rect(0,0, getParentPlotWidth(), ascent+descent);//plotBorderLeft-30); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(QPointF(left, bottom+parent->pt2px(painter, axisStyle.tickOutsideLength+axisStyle.tickLabelDistance+axisStyle.labelDistance)+labelMax.height())); //JKQTPEnhancedPainter::RenderHints h=painter.renderHints(); //painter.drawRect(rect); //painter.drawEllipse(-4, -4, 8, 8); switch(axisStyle.labelPosition) { case JKQTPLabelMax: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect); break; case JKQTPLabelMin: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect); break; case JKQTPLabelCenter: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect); break; } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("magenta"); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth/2.0); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); painter.drawRect(rect); } //painter.resetTransform(); } if (!axisLabel.isEmpty() && JKQTPCADrawModeHasAxisLabel(axisStyle.drawMode2)) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes(): axisLabel2").arg(objectName())); #endif getParentMathText()->setFontSize(axisStyle.labelFontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontRomanOrSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->parse(axisLabel); QRectF rect(0,0, getParentPlotWidth(), getParentMathText()->getSize(painter).height());//plotBorderLeft-30); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.translate(QPointF(left, top-parent->pt2px(painter, axisStyle.tickOutsideLength+axisStyle.tickLabelDistance+axisStyle.labelDistance)-labelMax.height()-rect.height())); //JKQTPEnhancedPainter::RenderHints h=painter.renderHints(); //painter.drawRect(rect); //painter.drawEllipse(-4, -4, 8, 8); switch(axisStyle.labelPosition) { case JKQTPLabelMax: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect); break; case JKQTPLabelMin: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect); break; case JKQTPLabelCenter: getParentMathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect); break; } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("magenta"); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth/2.0); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); painter.drawRect(rect); } //painter.resetTransform(); } if (getParent()->getCurrentPlotterStyle().debugShowRegionBoxes) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); QPen p("cyan"); QColor col=p.color(); col.setAlphaF(0.8); p.setColor(col); p.setWidthF(getParent()->getCurrentPlotterStyle().debugRegionLineWidth); painter.setPen(p); painter.setBrush(QBrush(QColor(Qt::transparent))); QSizeF s1,s2; s1=getSize1(painter); s2=getSize2(painter); painter.drawRect(QRectF(QPointF(left, bottom), s1)); painter.drawRect(QRectF(QPointF(left, top-s2.height()), s2)); } } JKQTPHorizontalIndependentAxis::JKQTPHorizontalIndependentAxis(double _axisOffset, double _axisWidth, double _otherAxisOffset, double _otherAxisWidth, JKQTBasePlotter* parent): JKQTPHorizontalAxis(parent), axisOffset(_axisOffset), axisWidth(_axisWidth), otherAxisWidth(_otherAxisOffset), otherAxisOffset(_otherAxisWidth), otherAxisInverted(false) { if (parent) { axisStyle=parent->getCurrentPlotterStyle().topColorbarAxisStyle; } else { axisStyle=JKQTPGetSystemDefaultBaseStyle().topColorbarAxisStyle; } } void JKQTPHorizontalIndependentAxis::setAxisOffset(double __value) { this->axisOffset = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPHorizontalIndependentAxis::setAxisWidth(double __value) { this->axisWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPHorizontalIndependentAxis::setOtherAxisOffset(double __value) { this->otherAxisOffset = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPHorizontalIndependentAxis::setOtherAxisWidth(double __value) { this->otherAxisWidth = __value; this->paramsChanged=true; redrawPlot(); } void JKQTPHorizontalIndependentAxis::setOtherAxisInverted(bool __value) { this->otherAxisInverted = __value; this->paramsChanged=true; redrawPlot(); } double JKQTPHorizontalIndependentAxis::getParentPlotWidth() const { return axisWidth; } double JKQTPHorizontalIndependentAxis::getParentPlotOffset() const { return axisOffset; } double JKQTPHorizontalIndependentAxis::getParentOtheraxisWidth() const { return otherAxisWidth; } bool JKQTPHorizontalIndependentAxis::getParentOtheraxisInverted() const { return otherAxisInverted; } double JKQTPHorizontalIndependentAxis::getParentOtheraxisOffset() const { return otherAxisOffset; }