mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-11-16 10:35:49 +08:00
2361 lines
94 KiB
C++
2361 lines
94 KiB
C++
/*
|
|
Copyright (c) 2008-2018 Jan W. Krieger (<jan@jkrieger.de>)
|
|
|
|
|
|
|
|
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 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
|
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
|
#include <QDebug>
|
|
#include <QDateTime>
|
|
#include <cfloat>
|
|
#include <QApplication>
|
|
|
|
|
|
//#undef SHOW_JKQTPLOTTER_DEBUG
|
|
//#define SHOW_JKQTPLOTTER_DEBUG
|
|
|
|
JKQTPcoordinateAxis::JKQTPcoordinateAxis(JKQtBasePlotter* parent): QObject(parent) {
|
|
this->parent=parent;
|
|
|
|
autoLabelDigits=true;
|
|
|
|
tickMode=def_tickMode=JKQTPLTMLinOrPower;
|
|
|
|
axisPrefix="";
|
|
scaleSign=1;
|
|
doUpdateScaling=true;
|
|
|
|
axismin=-10;
|
|
axismax=10;
|
|
axisabsoultemin=-DBL_MAX/100.0;
|
|
axisabsoultemax=DBL_MAX/100.0;
|
|
axisMinWidth=-1;
|
|
|
|
width=20;
|
|
|
|
scale=0;
|
|
offset=0;
|
|
inverted=false;
|
|
|
|
tickSpacing=0;
|
|
tickSpacingLog=10;
|
|
tickStart=0;
|
|
labelDigits=3;
|
|
|
|
autoAxisSpacing=def_autoAxisSpacing=true;
|
|
logAxis=def_logAxis=false;
|
|
minorTickLabelsEnabled=def_minorTickLabelsEnabled=false;
|
|
minorTickLabelFullNumber=def_minorTickLabelFullNumber=true;
|
|
logAxisBase=def_logAxisBase=10;
|
|
userTickSpacing=def_userTickSpacing=1;
|
|
userLogTickSpacing=def_userLogTickSpacing=10;
|
|
tickLabelAngle=def_tickLabelAngle=0;
|
|
|
|
labelType=def_labelType=JKQTPCALTexponent;
|
|
|
|
axisLabel="";
|
|
|
|
QFont f=QApplication::font();
|
|
|
|
labelPosition=def_labelPosition=JKQTPlabelCenter;
|
|
labelFont=def_labelFont=f.family(); //"Arial";
|
|
labelFontSize=def_labelFontSize=f.pointSizeF()+1; //12;
|
|
tickLabelFont=def_tickLabelFont=f.family(); //"Arial";
|
|
tickLabelFontSize=def_tickLabelFontSize=f.pointSizeF(); //10;
|
|
minorTickLabelFontSize=def_minorTickLabelFontSize=f.pointSizeF()*0.75; //10;
|
|
|
|
tickTimeFormat=def_tickTimeFormat=QLocale().timeFormat(QLocale::NarrowFormat);
|
|
tickDateFormat=def_tickDateFormat=QLocale().dateFormat(QLocale::NarrowFormat);
|
|
tickDateTimeFormat=def_tickDateTimeFormat=QLocale().dateTimeFormat(QLocale::NarrowFormat);
|
|
|
|
minTicks=def_minTicks=5;
|
|
minorTicks=def_minorTicks=1;
|
|
tickOutsideLength=def_tickOutsideLength=3;
|
|
minorTickOutsideLength=def_minorTickOutsideLength=1.5;
|
|
tickInsideLength=def_tickInsideLength=3;
|
|
minorTickInsideLength=def_minorTickInsideLength=1.5;
|
|
tickLabelDistance=def_tickLabelDistance=3;
|
|
labelDistance=def_labelDistance=5;
|
|
axisColor=def_axisColor=QColor("black");
|
|
showZeroAxis=def_showZeroAxis=true;
|
|
drawMode1=def_drawMode1=JKQTPCADMcomplete;
|
|
drawMode2=def_drawMode2=JKQTPCADMticks;
|
|
minorTickWidth=def_minorTickWidth=1;
|
|
tickWidth=def_tickWidth=1.5;
|
|
lineWidth=def_lineWidth=1.5;
|
|
lineWidthZeroAxis=def_lineWidthZeroAxis=1.5;
|
|
|
|
gridColor=def_gridColor=QColor("gray");
|
|
gridWidth=def_gridWidth=0.75;
|
|
gridStyle=def_gridStyle=Qt::DashLine;
|
|
drawGrid=def_drawGrid=true;
|
|
minorGridColor=def_minorGridColor=QColor("gray");
|
|
minorGridWidth=def_minorGridWidth=0.5;
|
|
minorGridStyle=def_minorGridStyle=Qt::DotLine;
|
|
drawMinorGrid=def_drawMinorGrid=false;
|
|
|
|
paramsChanged=true;
|
|
}
|
|
|
|
JKQTPcoordinateAxis::~JKQTPcoordinateAxis() {
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_parent(JKQtBasePlotter* parent) {
|
|
this->parent=parent;
|
|
QObject::setParent(parent);
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::update_plot() {
|
|
//if (paramsChanged) {
|
|
calcPlotScaling();
|
|
parent->update_plot();
|
|
//}
|
|
}
|
|
|
|
JKQTmathText* JKQTPcoordinateAxis::get_parent_mathText() {
|
|
return parent->get_mathText();
|
|
}
|
|
|
|
|
|
|
|
#define JKQTPPROPERTYloadFromAxis(settings, param) this->param=settings->param
|
|
|
|
|
|
void JKQTPcoordinateAxis::loadSettings(JKQTPcoordinateAxis* settings) {
|
|
JKQTPPROPERTYloadFromAxis(settings, showZeroAxis);
|
|
JKQTPPROPERTYloadFromAxis(settings, autoAxisSpacing);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickLabelsEnabled);
|
|
JKQTPPROPERTYloadFromAxis(settings, logAxis);
|
|
JKQTPPROPERTYloadFromAxis(settings, inverted);
|
|
JKQTPPROPERTYloadFromAxis(settings, logAxisBase);
|
|
JKQTPPROPERTYloadFromAxis(settings, userTickSpacing);
|
|
JKQTPPROPERTYloadFromAxis(settings, userLogTickSpacing);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickWidth);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickWidth);
|
|
JKQTPPROPERTYloadFromAxis(settings, lineWidth);
|
|
JKQTPPROPERTYloadFromAxis(settings, lineWidthZeroAxis);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, axisLabel);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, labelFont);
|
|
JKQTPPROPERTYloadFromAxis(settings, labelFontSize);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickLabelFont);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickLabelFontSize);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickLabelFontSize);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickLabelFullNumber);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, tickTimeFormat);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickDateFormat);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickDateTimeFormat);
|
|
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, minTicks);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTicks);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickOutsideLength);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickOutsideLength);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickInsideLength);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorTickInsideLength);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickLabelDistance);
|
|
JKQTPPROPERTYloadFromAxis(settings, labelDistance);
|
|
JKQTPPROPERTYloadFromAxis(settings, gridWidth);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorGridWidth);
|
|
JKQTPPROPERTYloadFromAxis(settings, drawGrid);
|
|
JKQTPPROPERTYloadFromAxis(settings, drawMinorGrid);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, labelPosition);
|
|
JKQTPPROPERTYloadFromAxis(settings, labelType);
|
|
JKQTPPROPERTYloadFromAxis(settings, axisColor);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, gridColor);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorGridColor);
|
|
JKQTPPROPERTYloadFromAxis(settings, gridStyle);
|
|
JKQTPPROPERTYloadFromAxis(settings, minorGridStyle);
|
|
|
|
JKQTPPROPERTYloadFromAxis(settings, drawMode1);
|
|
JKQTPPROPERTYloadFromAxis(settings, drawMode2);
|
|
JKQTPPROPERTYloadFromAxis(settings, tickMode);
|
|
paramsChanged=true;
|
|
calcPlotScaling();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::clearAxisTickLabels() {
|
|
tickLabels.clear();
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::addAxisTickLabel(double x, QString label) {
|
|
tickLabels.append(qMakePair(x, label));
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::addAxisTickLabels(const QVector<double> &x, const QStringList &label) {
|
|
for (int i=0; i<qMin(x.size(), label.size()); i++) {
|
|
tickLabels.append(qMakePair(x[i], label[i]));
|
|
}
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::addAxisTickLabels(const double *x, const QStringList &label) {
|
|
for (int i=0; i<label.size(); i++) {
|
|
tickLabels.append(qMakePair(x[i], label[i]));
|
|
}
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::addAxisTickLabels(const QVector<double> &x, const QString *label) {
|
|
for (int i=0; i<x.size(); i++) {
|
|
tickLabels.append(qMakePair(x[i], label[i]));
|
|
}
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::addAxisTickLabels(const double *x, const QString *label, int items) {
|
|
for (int i=0; i<items; i++) {
|
|
tickLabels.append(qMakePair(x[i], label[i]));
|
|
}
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::loadSettings(QSettings& settings, QString group) {
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, showZeroAxis, "show_zero_line", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, autoAxisSpacing, "auto_spacing", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, logAxis, "log", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickLabelsEnabled, "minorTickLabelsEnabled", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, inverted, "inverted", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, logAxisBase, "log_base", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, userTickSpacing, "tick_spacing", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, userLogTickSpacing, "log_tick_spacing", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickWidth, "minor_tick_width", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickWidth, "tick_width", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, lineWidth, "line_width", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, lineWidthZeroAxis, "line_width_zeroaxis", toDouble());
|
|
|
|
axisLabel=settings.value(group+axisPrefix+"axis_label", axisLabel).toString();
|
|
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, labelFont, "label_font", toString());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, labelFontSize, "label_font_size", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickLabelFont, "tick_label_font", toString());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickLabelFontSize, "tick_label_font_size", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickLabelFontSize, "minor_tick_label_font_size", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickLabelFullNumber, "minor_tick_label_full_number", toBool());
|
|
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickTimeFormat, "tick_time_format", toString());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickDateFormat, "tick_date_format", toString());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickDateTimeFormat, "tick_datetime_format", toString());
|
|
|
|
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minTicks, "min_ticks", toUInt());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTicks, "minor_ticks", toUInt());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickOutsideLength, "tick_outside_length", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickOutsideLength, "minor_tick_outside_length", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickInsideLength, "tick_inside_length", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorTickInsideLength, "minor_tick_inside_length", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, tickLabelDistance, "tick_label_distance", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, labelDistance, "label_distance", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, gridWidth, "grid_width", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, minorGridWidth, "minor_grid_width", toDouble());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, drawGrid, "draw_grid", toBool());
|
|
JKQTPPROPERTYload(settings, group+axisPrefix, drawMinorGrid, "draw_minor_grid", toBool());
|
|
|
|
labelPosition=String2JKQTPlabelPosition(settings.value(group+axisPrefix+"label_position", JKQTPlabelPosition2String(labelPosition)).toString());
|
|
labelType=String2JKQTPCAlabelType(settings.value(group+axisPrefix+"label_type", JKQTPCAlabelType2String(labelType)).toString());
|
|
axisColor=QColor(settings.value(group+axisPrefix+"color", JKQTP_QColor2String(axisColor)).toString());
|
|
|
|
gridColor=QColor(settings.value(group+axisPrefix+"grid_color", JKQTP_QColor2String(gridColor)).toString());
|
|
minorGridColor=QColor(settings.value(group+axisPrefix+"minor_grid_color", JKQTP_QColor2String(minorGridColor)).toString());
|
|
gridStyle=JKQTP_String2QPenStyle(settings.value(group+axisPrefix+"grid_style", JKQTP_QPenStyle2String(gridStyle)).toString());
|
|
minorGridStyle=JKQTP_String2QPenStyle(settings.value(group+axisPrefix+"minor_grid_style", JKQTP_QPenStyle2String(minorGridStyle)).toString());
|
|
|
|
drawMode1=String2JKQTPCAdrawMode(settings.value(group+axisPrefix+"draw_mode1", JKQTPCAdrawMode2String(drawMode1)).toString());
|
|
drawMode2=String2JKQTPCAdrawMode(settings.value(group+axisPrefix+"draw_mode2", JKQTPCAdrawMode2String(drawMode2)).toString());
|
|
tickMode=String2JKQTPLabelTickMode(settings.value(group+axisPrefix+"tick_mode", JKQTPLabelTickMode2String(tickMode)).toString());
|
|
paramsChanged=true;
|
|
calcPlotScaling();
|
|
}
|
|
|
|
|
|
|
|
void JKQTPcoordinateAxis::saveSettings(QSettings& settings, QString group) {
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, showZeroAxis, "show_zero_line");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, autoAxisSpacing, "auto_spacing");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, logAxis, "log");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickLabelsEnabled, "minorTickLabelsEnabled");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, logAxisBase, "log_base");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, userTickSpacing, "tick_spacing");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, userLogTickSpacing, "log_tick_spacing");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickWidth, "minor_tick_width");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickWidth, "tick_width");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, lineWidth, "line_width");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, lineWidthZeroAxis, "line_width_zeroaxis");
|
|
|
|
settings.setValue(group+axisPrefix+"label", axisLabel);
|
|
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, labelFont, "label_font");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, labelFontSize, "label_font_size");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickLabelFont, "tick_label_font");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickLabelFontSize, "tick_label_font_size");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickLabelFontSize, "minor_tick_label_font_size");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickLabelFullNumber, "minor_tick_label_full_number");
|
|
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickTimeFormat, "tick_time_format");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickDateFormat, "tick_date_format");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickDateTimeFormat, "tick_datetime_format");
|
|
|
|
|
|
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minTicks, "min_ticks");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTicks, "minor_ticks");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickOutsideLength, "tick_outside_length");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickOutsideLength, "minor_tick_outside_length");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickInsideLength, "tick_inside_length");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorTickInsideLength, "minor_tick_inside_length");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, tickLabelDistance, "tick_label_distance");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, labelDistance, "label_distance");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, gridWidth, "grid_width");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, minorGridWidth, "minor_grid_width");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, drawGrid, "draw_grid");
|
|
JKQTPPROPERTYsave(settings, group+axisPrefix, drawMinorGrid, "draw_minor_grid");
|
|
|
|
if (labelPosition!=def_labelPosition) settings.setValue(group+axisPrefix+"label_position", JKQTPlabelPosition2String(labelPosition));
|
|
if (labelType!=def_labelType) settings.setValue(group+axisPrefix+"label_type", JKQTPCAlabelType2String(labelType));
|
|
if (axisColor!=def_axisColor) settings.setValue(group+axisPrefix+"color", JKQTP_QColor2String(axisColor));
|
|
if (drawMode1!=def_drawMode1) settings.setValue(group+axisPrefix+"draw_mode1", JKQTPCAdrawMode2String(drawMode1));
|
|
if (drawMode2!=def_drawMode2) settings.setValue(group+axisPrefix+"draw_mode2", JKQTPCAdrawMode2String(drawMode2));
|
|
if (tickMode!=def_tickMode) settings.setValue(group+axisPrefix+"tick_mode", JKQTPLabelTickMode2String(tickMode));
|
|
if (gridColor!=def_gridColor) settings.setValue(group+axisPrefix+"grid_color", JKQTP_QColor2String(gridColor));
|
|
if (minorGridColor!=def_minorGridColor) settings.setValue(group+axisPrefix+"minor_grid_style", JKQTP_QPenStyle2String(minorGridStyle));
|
|
if (gridStyle!=def_gridStyle) settings.setValue(group+axisPrefix+"grid_color", JKQTP_QColor2String(gridColor));
|
|
if (minorGridStyle!=def_minorGridStyle) settings.setValue(group+axisPrefix+"minor_grid_style", JKQTP_QPenStyle2String(minorGridStyle));
|
|
}
|
|
|
|
double JKQTPcoordinateAxis::calcLinearTickSpacing() {
|
|
if (labelType==JKQTPCALTdate) {
|
|
QDateTime dt;
|
|
dt.setMSecsSinceEpoch(0);
|
|
//qDebug()<<" dt="<<dt;
|
|
dt=dt.addYears(1);
|
|
//qDebug()<<dt;
|
|
double deltaDT=dt.toMSecsSinceEpoch();
|
|
//qDebug()<<dt<<dt.toMSecsSinceEpoch()<<deltaDT;
|
|
int level=0;
|
|
double TickSpacing=deltaDT;
|
|
QVector<double> tickbase;
|
|
tickbase<<1<< 2<< 5<<10<<20<<50<<100<<200<<500<<1000;
|
|
//qDebug()<<"startexponent="<<startexponent<<" width="<<width;
|
|
unsigned int current_tickbase=tickbase.size();
|
|
unsigned int tick_count=0;
|
|
int cnt=0;
|
|
do {
|
|
if (current_tickbase==0) {
|
|
level++;
|
|
if (level==1) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addMonths(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<< 6<<12;
|
|
} else if (level==2) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addDays(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<< 6<<12;
|
|
} else if (level>=3) {
|
|
break;
|
|
}
|
|
current_tickbase=tickbase.size()-1;
|
|
} else current_tickbase--;
|
|
TickSpacing=tickbase[current_tickbase]*deltaDT;
|
|
tick_count=(unsigned int)round(width/TickSpacing);
|
|
//qDebug()<<"current_tickbase="<<tickbase[current_tickbase]<<" level="<<level<<" tTickSpacing="<<TickSpacing<<" deltaDT="<<deltaDT<<" tick_count="<<tick_count;
|
|
cnt++;
|
|
} while (level<=3 && tick_count<minTicks && cnt<1000);
|
|
|
|
// the cnt variable exists for savety reasons to prevent an endless loop!
|
|
if (cnt>=1000) TickSpacing=width/(double)minTicks;
|
|
//qDebug()<<"TickSpacing="<<TickSpacing<<" cnt="<<cnt;
|
|
return TickSpacing;
|
|
} else if (labelType==JKQTPCALTdatetime) {
|
|
QDateTime dt;
|
|
dt.setMSecsSinceEpoch(0);
|
|
//qDebug()<<" dt="<<dt;
|
|
dt=dt.addYears(1);
|
|
//qDebug()<<dt;
|
|
double deltaDT=dt.toMSecsSinceEpoch();
|
|
//qDebug()<<dt<<dt.toMSecsSinceEpoch()<<deltaDT;
|
|
int level=0;
|
|
double TickSpacing=deltaDT;
|
|
QVector<double> tickbase;
|
|
tickbase<<1<< 2<< 5<<10<<20<<50<<100<<200<<500<<1000;
|
|
//qDebug()<<"startexponent="<<startexponent<<" width="<<width;
|
|
unsigned int current_tickbase=tickbase.size();
|
|
unsigned int tick_count=0;
|
|
int cnt=0;
|
|
do {
|
|
if (current_tickbase==0) {
|
|
level++;
|
|
if (level==1) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addMonths(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<< 6<<12;
|
|
} else if (level==2) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addDays(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<< 6<<12;
|
|
} else if (level==3) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addSecs(60*60);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<< 6<<12<<24;
|
|
} else if (level==4) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addSecs(60);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<<5<<15<<20<<30<<45<<60<<120;
|
|
} else if (level==5) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addSecs(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<<5<<15<<20<<30<<45<<60<<120;
|
|
} else if (level>=6) {
|
|
break;
|
|
}
|
|
current_tickbase=tickbase.size()-1;
|
|
} else current_tickbase--;
|
|
TickSpacing=tickbase[current_tickbase]*deltaDT;
|
|
tick_count=(unsigned int)round(width/TickSpacing);
|
|
//qDebug()<<"current_tickbase="<<tickbase[current_tickbase]<<" level="<<level<<" tTickSpacing="<<TickSpacing<<" deltaDT="<<deltaDT<<" tick_count="<<tick_count;
|
|
cnt++;
|
|
} while (level<6 && tick_count<minTicks && cnt<1000);
|
|
|
|
// the cnt variable exists for savety reasons to prevent an endless loop!
|
|
if (cnt>=1000) TickSpacing=width/(double)minTicks;
|
|
//qDebug()<<"TickSpacing="<<TickSpacing<<" cnt="<<cnt;
|
|
return TickSpacing;
|
|
} else if (labelType==JKQTPCALTtime) {
|
|
QDateTime dt;
|
|
dt.setMSecsSinceEpoch(0);
|
|
//qDebug()<<" dt="<<dt;
|
|
dt=dt.addSecs(60*60);
|
|
//qDebug()<<dt;
|
|
double deltaDT=dt.toMSecsSinceEpoch();
|
|
//qDebug()<<dt<<dt.toMSecsSinceEpoch()<<deltaDT;
|
|
int level=0;
|
|
double TickSpacing=deltaDT;
|
|
QVector<double> tickbase;
|
|
tickbase<<1<< 2<< 5<<10<<20<<50<<100<<200<<500<<1000;
|
|
//qDebug()<<"startexponent="<<startexponent<<" width="<<width;
|
|
unsigned int current_tickbase=tickbase.size();
|
|
unsigned int tick_count=0;
|
|
int cnt=0;
|
|
do {
|
|
if (current_tickbase==0) {
|
|
level++;
|
|
if (level==1) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addSecs(60);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<<5<<15<<20<<30<<45<<60<<120;
|
|
} else if (level==2) {
|
|
dt.setMSecsSinceEpoch(0);
|
|
dt=dt.addSecs(1);
|
|
deltaDT=dt.toMSecsSinceEpoch();
|
|
tickbase.clear();
|
|
tickbase<<1<< 2<<5<<15<<20<<30<<45<<60<<120;
|
|
} else if (level>=3) {
|
|
break;
|
|
}
|
|
current_tickbase=tickbase.size()-1;
|
|
} else current_tickbase--;
|
|
TickSpacing=tickbase[current_tickbase]*deltaDT;
|
|
tick_count=(unsigned int)round(width/TickSpacing);
|
|
//qDebug()<<"current_tickbase="<<tickbase[current_tickbase]<<" level="<<level<<" tTickSpacing="<<TickSpacing<<" deltaDT="<<deltaDT<<" tick_count="<<tick_count;
|
|
cnt++;
|
|
} while (level<3 && tick_count<minTicks && cnt<1000);
|
|
|
|
// the cnt variable exists for savety reasons to prevent an endless loop!
|
|
if (cnt>=1000) TickSpacing=width/(double)minTicks;
|
|
//qDebug()<<"TickSpacing="<<TickSpacing<<" cnt="<<cnt;
|
|
return TickSpacing;
|
|
} else {
|
|
double TickSpacing=1;
|
|
int startexponent=(int)floor(log10(width))+3;
|
|
double tickbase[]={1, 2, 2.5, 5, 10};
|
|
int tb_max=4;
|
|
//qDebug()<<"startexponent="<<startexponent<<" width="<<width;
|
|
int current_exponent=startexponent;
|
|
unsigned int current_tickbase=tb_max+1;
|
|
unsigned int tick_count=0;
|
|
int cnt=0;
|
|
do {
|
|
if (current_tickbase==0) {
|
|
current_tickbase=tb_max;
|
|
current_exponent--;
|
|
} else current_tickbase--;
|
|
TickSpacing=tickbase[current_tickbase]*pow(10,current_exponent);
|
|
tick_count=(unsigned int)round(width/TickSpacing);
|
|
//qDebug()<<"current_tickbase="<<tickbase[current_tickbase]<<" current_exponent="<<current_exponent<<" tTickSpacing="<<TickSpacing<<" tick_count="<<tick_count;
|
|
cnt++;
|
|
} while (tick_count<minTicks && cnt<1000);
|
|
|
|
// the cnt variable exists for savety reasons to prevent an endless loop!
|
|
if (cnt>=1000) TickSpacing=width/(double)minTicks;
|
|
//qDebug()<<"TickSpacing="<<TickSpacing<<" cnt="<<cnt;
|
|
return TickSpacing;
|
|
}
|
|
}
|
|
|
|
|
|
double JKQTPcoordinateAxis::calcLogTickSpacing() {
|
|
double TickSpacing=logAxisBase;
|
|
if (fabs(log(axismax)-log(axismin))/log(logAxisBase)>2*minTicks) {
|
|
double power=1;
|
|
int cnt=0;
|
|
while (fabs(log(axismax)-log(axismin))/log(logAxisBase)/power>2*minTicks && cnt<1000) {
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
//qDebug()<<cnt<<power<<log(width)/log(logAxisBase)/power<<2*minTicks;
|
|
#endif
|
|
power++;
|
|
cnt++;
|
|
}
|
|
if (cnt<1000) TickSpacing=pow(logAxisBase, power);
|
|
}
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
//qDebug()<<"log-tick-spacing: "<<TickSpacing;
|
|
#endif
|
|
return TickSpacing;
|
|
|
|
}
|
|
|
|
|
|
QString JKQTPcoordinateAxis::floattolabel(double data) {
|
|
int past_comma=labelDigits;
|
|
bool remove_trail0=true;
|
|
QLocale loc=QLocale::system();
|
|
loc.setNumberOptions(QLocale::OmitGroupSeparator);
|
|
|
|
switch(labelType) {
|
|
case JKQTPCALTdefault: {
|
|
QString res=loc.toString(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;
|
|
}; break;
|
|
case JKQTPCALTexponent: {
|
|
return QString(jkqtp_floattolatexstr(data, past_comma, remove_trail0, 1e-300, 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(tickDateFormat);
|
|
}; break;
|
|
case JKQTPCALTtime: {
|
|
QDateTime dt;
|
|
dt.setMSecsSinceEpoch(uint64_t(data));
|
|
return dt.toString(tickTimeFormat);
|
|
}; break;
|
|
case JKQTPCALTdatetime: {
|
|
QDateTime dt;
|
|
dt.setMSecsSinceEpoch(uint64_t(data));
|
|
return dt.toString(tickDateTimeFormat);
|
|
}; break;
|
|
default:
|
|
return QString();
|
|
break;
|
|
}
|
|
|
|
/*
|
|
tickTimeFormat
|
|
tickDateFormat
|
|
tickDateTimeFormat
|
|
**/
|
|
|
|
return QString();
|
|
}
|
|
|
|
QString JKQTPcoordinateAxis::floattolabel(double data, int past_comma) {
|
|
bool remove_trail0=true;
|
|
QLocale loc=QLocale::system();
|
|
loc.setNumberOptions(QLocale::OmitGroupSeparator);
|
|
if (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 (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 (labelType==JKQTPCALTexponentCharacter) return QString(jkqtp_floattounitstr(data, past_comma, remove_trail0).c_str());
|
|
return "";
|
|
}
|
|
|
|
int JKQTPcoordinateAxis::calcLinearUnitDigits() {
|
|
if (!autoLabelDigits) return labelDigits;
|
|
int unitdigits=-1;
|
|
double minval=tickStart;
|
|
bool equals=true;
|
|
/*for (int i=0; i<20; i++) {
|
|
equals=equals || (floattolabel((minval+(double)i*tickSpacing), unitdigits)== floattolabel((minval+(double)(i+1)*tickSpacing), unitdigits));
|
|
}*/
|
|
while ((unitdigits<20) && equals) {
|
|
unitdigits++;
|
|
equals=false;
|
|
for (int i=-10; i<10; i++) {
|
|
QString l1=floattolabel((minval+(double)i*tickSpacing), unitdigits+2);
|
|
QString l2=floattolabel((minval+(double)(i+1.0)*tickSpacing), unitdigits+2);
|
|
//qDebug()<<"unitdigits="<<unitdigits<<" l1="<<l1<<" l2="<<l2;
|
|
equals=equals || (l1==l2);
|
|
}
|
|
}
|
|
return unitdigits+2;
|
|
}
|
|
|
|
|
|
void JKQTPcoordinateAxis::calcPlotScaling(bool force) {
|
|
#ifdef JKQTBP_AUTOTIMER
|
|
JKQTPAutoOutputTimer jkaat(QString("JKQtBasePlotter[%1]::calcPlotScaling()").arg(objectName()));
|
|
#endif
|
|
if (!doUpdateScaling) return;
|
|
if (!force && !paramsChanged) return;
|
|
if (axismin>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, (int)log10(axismin));
|
|
if (axismax<axismin) {
|
|
std::swap(axismin, axismax);
|
|
} else if (axismax==axismin) {
|
|
axismax=axismin+pow(10.0, (int)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="<<width<<"\n";
|
|
|
|
|
|
double plotOffset=get_parent_plotoffset();
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
//qDebug()<<get_parent()->objectName()<<": inverted = "<<inverted;
|
|
//qDebug()<<get_parent()->objectName()<<": plotOffset = "<<plotOffset;
|
|
//qDebug()<<get_parent()->objectName()<<": plotWidth = "<<get_parent_plotwidth();
|
|
#endif
|
|
if (isLogAxis()) {
|
|
scale=get_parent_plotwidth()/(log(axismax)-log(axismin))*log(logAxisBase);
|
|
if (scaleSign>0) {
|
|
offset=plotOffset-log(axismin)/log(logAxisBase)*scale;
|
|
} else {
|
|
offset=plotOffset+log(axismax)/log(logAxisBase)*scale;
|
|
}
|
|
} else {
|
|
scale=get_parent_plotwidth()/width;
|
|
if (scaleSign>0) {
|
|
offset=plotOffset-axismin*scale;
|
|
} else {
|
|
offset=plotOffset+axismax*scale;
|
|
}
|
|
|
|
}
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
//qDebug()<<get_parent()->objectName()<<": offset = "<<offset;
|
|
//qDebug()<<get_parent()->objectName()<<": scale = "<<scale;
|
|
//qDebug()<<get_parent()->objectName()<<": scaleSign = "<<scaleSign;
|
|
#endif
|
|
// now we try to find a suitable tick and grid line spacing so that
|
|
// between maxTicks and minTicks ticks fit into twidth
|
|
// if autoXAxisSpacing/autoYAxisSpacing is false then the spacing properties
|
|
// are calculated from the user-supplied parameters currently there is no
|
|
// autoscaling for the logarithmic plots available
|
|
if (tickMode==JKQTPLTMLinOrPower) {
|
|
if (logAxis) {
|
|
tickSpacing=1;
|
|
tickSpacingLog=calcLogTickSpacing();
|
|
tickStart=pow(logAxisBase, floor(log(axismin)/log(logAxisBase)));
|
|
} else {
|
|
if (autoAxisSpacing) {
|
|
// autoscaling linear x-axis
|
|
tickSpacingLog=10;
|
|
tickSpacing=calcLinearTickSpacing();
|
|
} else {
|
|
// predefined scaling for linear x-axis
|
|
tickSpacing=userTickSpacing;
|
|
tickSpacingLog=userLogTickSpacing;
|
|
}
|
|
tickStart=floor(axismin/(tickSpacing))*tickSpacing;
|
|
}
|
|
} else if (tickMode==JKQTPLTMLin) {
|
|
if (autoAxisSpacing) {
|
|
// autoscaling linear x-axis
|
|
tickSpacingLog=10;
|
|
tickSpacing=calcLinearTickSpacing();
|
|
} else {
|
|
// predefined scaling for linear x-axis
|
|
tickSpacing=userTickSpacing;
|
|
tickSpacingLog=userLogTickSpacing;
|
|
}
|
|
tickStart=floor(axismin/(tickSpacing))*tickSpacing;
|
|
} else if (tickMode==JKQTPLTMPower) {
|
|
tickSpacing=1;
|
|
tickSpacingLog=calcLogTickSpacing();
|
|
tickStart=pow(logAxisBase, floor(log(axismin)/log(logAxisBase)));
|
|
}
|
|
|
|
|
|
labelDigits=calcLinearUnitDigits();
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
//qDebug()<<" tickStart="<<tickStart<<"\n";
|
|
//qDebug()<<" tickSpacing="<<tickSpacing<<"\n";
|
|
//qDebug()<<" labelDigits="<<labelDigits<<"\n";
|
|
#endif
|
|
paramsChanged=false;
|
|
|
|
}
|
|
|
|
bool JKQTPcoordinateAxis::isLogAxis() const {
|
|
return logAxis || (tickMode==JKQTPLTMPower);
|
|
}
|
|
|
|
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)<axisMinWidth) {
|
|
amax=amin+axisMinWidth;
|
|
}
|
|
|
|
axismin=amin;
|
|
axismax=amax;
|
|
|
|
if (amin<axisabsoultemin) axismin=axisabsoultemin;
|
|
if (amax>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)<axisMinWidth) {
|
|
axismax=axismin+axisMinWidth;
|
|
}
|
|
if (fabs(axismax-axismin)<1e-308) {
|
|
axismax=axismin+1;
|
|
}
|
|
if (oldamin!=axismin || oldamax!=axismax) {
|
|
paramsChanged=true;
|
|
calcPlotScaling();
|
|
update_plot();
|
|
}
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::setNoAbsoluteRange() {
|
|
axisabsoultemin=-DBL_MAX;
|
|
axisabsoultemax=DBL_MAX;
|
|
setRange(axismin, axismax);
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickSpacing(double __value) {
|
|
this->tickSpacing = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_axisMinWidth(double __value) {
|
|
this->axisMinWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_autoAxisSpacing(bool __value) {
|
|
this->autoAxisSpacing = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickLabelsEnabled(bool __value) {
|
|
this->minorTickLabelsEnabled = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_logAxis(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));
|
|
}
|
|
if (this->isLogAxis() && this->minorTicks==def_minorTicks) {
|
|
this->minorTicks=9;
|
|
}
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_logAxisBase(double __value) {
|
|
this->logAxisBase = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_userTickSpacing(double __value) {
|
|
this->userTickSpacing = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_userLogTickSpacing(double __value) {
|
|
this->userLogTickSpacing = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelType(JKQTPCAlabelType __value) {
|
|
this->labelType = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickMode(JKQTPLabelTickMode __value)
|
|
{
|
|
this->tickMode = __value;
|
|
this->paramsChanged=true;
|
|
set_logAxis(this->logAxis);
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickMode(int __value) {
|
|
set_tickMode(JKQTPLabelTickMode(__value));
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_axisLabel(QString __value) {
|
|
this->axisLabel = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelPosition(JKQTPlabelPosition __value) {
|
|
this->labelPosition = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelFont(QString __value) {
|
|
this->labelFont = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelFontSize(double __value) {
|
|
this->labelFontSize = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickLabelFont(QString __value) {
|
|
this->tickLabelFont = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickTimeFormat(QString __value) {
|
|
this->tickTimeFormat = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickDateFormat(QString __value) {
|
|
this->tickDateFormat = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickDateTimeFormat(QString __value) {
|
|
this->tickDateTimeFormat = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickLabelFontSize(double __value) {
|
|
this->tickLabelFontSize = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickLabelFontSize(double __value) {
|
|
this->minorTickLabelFontSize = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickLabelFullNumber(bool __value) {
|
|
this->minorTickLabelFullNumber = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minTicks(unsigned int __value) {
|
|
this->minTicks = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTicks(unsigned int __value) {
|
|
this->minorTicks = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTicks(int __value) {
|
|
this->minorTicks = qMax(int(0), __value);
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickOutsideLength(double __value) {
|
|
this->tickOutsideLength = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickOutsideLength(double __value) {
|
|
this->minorTickOutsideLength = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickInsideLength(double __value) {
|
|
this->tickInsideLength = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickInsideLength(double __value) {
|
|
this->minorTickInsideLength = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_axisColor(QColor __value) {
|
|
this->axisColor = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_showZeroAxis(bool __value) {
|
|
this->showZeroAxis = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_inverted(bool __value) {
|
|
this->inverted = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_gridColor(QColor __value) {
|
|
this->gridColor = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorGridColor(QColor __value) {
|
|
this->minorGridColor = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_gridWidth(double __value) {
|
|
this->gridWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_gridStyle(Qt::PenStyle __value) {
|
|
this->gridStyle = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorGridWidth(double __value) {
|
|
this->minorGridWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorGridStyle(Qt::PenStyle __value) {
|
|
this->minorGridStyle = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_drawMode1(JKQTPCAdrawMode __value) {
|
|
this->drawMode1 = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_drawMode2(JKQTPCAdrawMode __value) {
|
|
this->drawMode2 = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_minorTickWidth(double __value) {
|
|
this->minorTickWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickWidth(double __value) {
|
|
this->tickWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_lineWidth(double __value) {
|
|
this->lineWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_lineWidthZeroAxis(double __value) {
|
|
this->lineWidthZeroAxis = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickLabelDistance(double __value) {
|
|
this->tickLabelDistance = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelDistance(double __value) {
|
|
this->labelDistance = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_labelDigits(int __value) {
|
|
this->labelDigits = __value;
|
|
this->paramsChanged=true;
|
|
this->autoLabelDigits=false;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_drawGrid(bool __value) {
|
|
this->drawGrid = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_drawMinorGrid(bool __value) {
|
|
this->drawMinorGrid = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPcoordinateAxis::set_tickLabelAngle(double __value) {
|
|
this->tickLabelAngle = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
|
|
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();
|
|
update_plot();*/
|
|
}
|
|
|
|
double JKQTPcoordinateAxis::getNextLabelDistance(double x) {
|
|
if (tickMode==JKQTPLTMLinOrPower) {
|
|
if (logAxis) {
|
|
return x*tickSpacingLog;
|
|
} else {
|
|
return tickSpacing;
|
|
}
|
|
} else if (tickMode==JKQTPLTMLin) {
|
|
return tickSpacing;
|
|
} else if (tickMode==JKQTPLTMPower) {
|
|
return x*tickSpacingLog;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool JKQTPcoordinateAxis::getNextLabel(double& x, QString& label, bool init) {
|
|
//qDebug()<<"start JKQTPcoordinateAxis::getNextLabel("<<x<<label<<init<<")";
|
|
label="";
|
|
if (tickLabels.size()<=0) {
|
|
if (init) {
|
|
x=tickStart;
|
|
label=floattolabel(x);
|
|
return true;
|
|
} else {
|
|
if (tickMode==JKQTPLTMLinOrPower) {
|
|
if (logAxis) {
|
|
x*=tickSpacingLog;
|
|
} else {
|
|
x=x+tickSpacing;
|
|
}
|
|
} else if (tickMode==JKQTPLTMLin) {
|
|
x=x+tickSpacing;
|
|
} else if (tickMode==JKQTPLTMPower) {
|
|
x*=tickSpacingLog;
|
|
}
|
|
}
|
|
if (x>=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<tickLabels.size(); i++) {
|
|
if (x==tickLabels[i].first && i+1<tickLabels.size()) {
|
|
if (x>=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(tickLabelFont);
|
|
f.setPointSizeF(tickLabelFontSize*parent->get_fontSizeMultiplier());
|
|
QFontMetricsF fm(f);
|
|
//get_parent_mathText()->set_fontSize(f.pointSizeF());
|
|
//get_parent_mathText()->set_fontRoman(f.family());
|
|
bool first=true;
|
|
int cnt=0;
|
|
while (getNextLabel(x, label, first) && cnt<50) {
|
|
double width, ascent, descent, strikeoutPos;
|
|
/*if (label.contains("\\") || label.contains("$") || label.contains("^") || label.contains("_")) {
|
|
get_parent_mathText()->parse(label);
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
} else {
|
|
width=fm.width(label);
|
|
ascent=fm.ascent();
|
|
descent=fm.descent();
|
|
strikeoutPos=fm.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() = ["<<w<<", "<<h<<"]\n";
|
|
if (ascent) *ascent=a;
|
|
if (descent) *descent=h-a;
|
|
if (tickLabelAngle!=0) {
|
|
QRectF r(0,0,w,h);
|
|
return jkqtpRotateRect(r, tickLabelAngle).boundingRect().size();
|
|
} else {
|
|
return QSizeF(w, h);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPverticalAxis::JKQTPverticalAxis(JKQtBasePlotter* parent):
|
|
JKQTPcoordinateAxis(parent)
|
|
{
|
|
//axisPrefix="yaxis_";
|
|
scaleSign=-1;
|
|
}
|
|
|
|
double JKQTPverticalAxis::get_parent_plotwidth() const {
|
|
return parent->get_plotHeight();
|
|
}
|
|
|
|
double JKQTPverticalAxis::get_parent_plotoffset() const {
|
|
return parent->get_iplotBorderTop();
|
|
}
|
|
|
|
QSize JKQTPverticalAxis::getSize1(JKQTPEnhancedPainter& painter) {
|
|
if (drawMode1==JKQTPCADMnone || drawMode1==JKQTPCADMline) return QSize(0, get_parent_plotwidth());
|
|
if (drawMode1==JKQTPCADMticks) return QSize(parent->pt2px(painter, tickOutsideLength), get_parent_plotwidth());
|
|
// find out the maximum width over all visible plot labels
|
|
double tlwidth=getMaxTickLabelSize(painter).width();
|
|
if (drawMode1==JKQTPCADMticksAndLabels) return QSize(parent->pt2px(painter, tickOutsideLength+tickLabelDistance)+tlwidth, get_parent_plotwidth());
|
|
|
|
// find out size of axis label
|
|
/*get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double lwidth=get_parent_mathText()->getSize(painter).height();*/
|
|
double lwidth=parent->getTextSizeSize(labelFont, labelFontSize*parent->get_fontSizeMultiplier(), axisLabel, painter).height();
|
|
if (drawMode1==JKQTPCADMcomplete) return QSize(parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+tlwidth+lwidth, get_parent_plotwidth());
|
|
|
|
return QSize(0,0);
|
|
}
|
|
|
|
QSize JKQTPverticalAxis::getSize2(JKQTPEnhancedPainter& painter) {
|
|
if (drawMode2==JKQTPCADMnone || drawMode2==JKQTPCADMline) return QSize(0, get_parent_plotwidth());
|
|
if (drawMode2==JKQTPCADMticks) return QSize(parent->pt2px(painter, tickOutsideLength),get_parent_plotwidth());
|
|
// find out the maximum width over all visible plot labels
|
|
double tlwidth=getMaxTickLabelSize(painter).width();
|
|
if (drawMode2==JKQTPCADMticksAndLabels) return QSize(parent->pt2px(painter, tickOutsideLength+tickLabelDistance)+tlwidth, get_parent_plotwidth());
|
|
|
|
// find out size of axis label
|
|
/*get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double lwidth=get_parent_mathText()->getSize(painter).height();*/
|
|
double lwidth=parent->getTextSizeSize(labelFont, labelFontSize*parent->get_fontSizeMultiplier(), axisLabel, painter).height();
|
|
if (drawMode2==JKQTPCADMcomplete) return QSize(parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+tlwidth+lwidth, get_parent_plotwidth());
|
|
|
|
return QSize(0,0);
|
|
}
|
|
|
|
|
|
double JKQTPverticalAxis::get_parent_otheraxis_offset() const {
|
|
return parent->x2p(parent->getXMin());
|
|
}
|
|
|
|
|
|
double JKQTPverticalAxis::get_parent_otheraxis_width() const {
|
|
return fabs(parent->x2p(parent->getXMax())-parent->x2p(parent->getXMin()));
|
|
}
|
|
|
|
bool JKQTPverticalAxis::get_parent_otheraxis_inverted() const
|
|
{
|
|
return parent->getXAxis()->get_inverted();
|
|
}
|
|
|
|
void JKQTPverticalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
|
|
//qDebug()<<" start JKQTPverticalAxis::drawGrids(";
|
|
painter.save();
|
|
QPen pg=painter.pen();
|
|
pg.setColor(gridColor);
|
|
pg.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, gridWidth*parent->get_lineWidthMultiplier())));
|
|
pg.setStyle(gridStyle);
|
|
QPen pmg=painter.pen();
|
|
pmg.setColor(minorGridColor);
|
|
pmg.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH,parent->pt2px(painter, minorGridWidth*parent->get_lineWidthMultiplier())));
|
|
pmg.setStyle(minorGridStyle);
|
|
//double top=x2p(axismax);
|
|
//double bottom=x2p(axismin);
|
|
double left=0;
|
|
double right=0;
|
|
if (get_parent_otheraxis_inverted()) {
|
|
left=get_parent_otheraxis_offset()-get_parent_otheraxis_width();//;
|
|
right=get_parent_otheraxis_offset();//;
|
|
} else {
|
|
left=get_parent_otheraxis_offset();//;
|
|
right=get_parent_otheraxis_offset()+get_parent_otheraxis_width();//;
|
|
}
|
|
|
|
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<QLineF> lines_pg;
|
|
QVector<QLineF> lines_pmg;
|
|
while (getNextLabel(x, label, first) && (cnt<200)) {
|
|
double w=getNextLabelDistance(x);
|
|
double mtdist=w/(double)(minorTicks+1);
|
|
|
|
double xx=x2p(x);
|
|
//qDebug()<<" tick @ x="<<x<<" label="<<label<<" mtdist="<<mtdist<<" minorTicks="<<minorTicks;
|
|
|
|
//painter.setPen(pg);
|
|
//qDebug()<<" 1";
|
|
if (drawGrid && (x<axismax) && (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) && drawMinorGrid && (minorTicks>0) && (fabs(right-left)>0)) {
|
|
//qDebug()<<" 3.1";
|
|
double mx=x+mtdist;
|
|
//qDebug()<<" 3.2";
|
|
for (int i=0; i<(int)minorTicks; i++) {
|
|
//qDebug()<<" 3.2.1";
|
|
double mxx=x2p(mx);
|
|
//qDebug()<<" 3.2.2";
|
|
if ((mx<axismax) && (mx>axismin) && (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);
|
|
painter.restore();
|
|
//qDebug()<<" end JKQTPverticalAxis::drawGrids(";
|
|
}
|
|
|
|
void JKQTPverticalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, const QString& label, double fontSize)
|
|
{
|
|
get_parent_mathText()->set_fontSize(fontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
get_parent_mathText()->parse(label);
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
if (drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete) {
|
|
double lx=xx-parent->pt2px(painter, minorTickOutsideLength+tickLabelDistance)-width;
|
|
if (tickLabelAngle==90) {
|
|
painter.save();
|
|
painter.translate(lx+width-1.25*strikeoutPos, yy-width/2.0);
|
|
painter.rotate(tickLabelAngle);
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else if (tickLabelAngle==-90) {
|
|
painter.save();
|
|
painter.translate(lx+width-0.25*strikeoutPos, yy+width/2.0);
|
|
painter.rotate(tickLabelAngle);
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
if (tickLabelAngle>0) {
|
|
painter.translate(lx-strikeoutPos+(width)*(1.0-cos(fabs(tickLabelAngle)/180.0*M_PI)), yy+strikeoutPos-width*sin(fabs(tickLabelAngle)/180.0*M_PI));
|
|
painter.rotate(tickLabelAngle);
|
|
} else {
|
|
painter.translate(lx+strikeoutPos+(width-strikeoutPos)*(1.0-cos(fabs(tickLabelAngle)/180.0*M_PI)), yy+strikeoutPos+width*sin(fabs(tickLabelAngle)/180.0*M_PI));
|
|
painter.rotate(tickLabelAngle);
|
|
}
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, lx, yy+strikeoutPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPverticalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, const QString &label, double fontSize)
|
|
{
|
|
get_parent_mathText()->set_fontSize(fontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
get_parent_mathText()->parse(label);
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
|
|
if (drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete) {
|
|
double lx=xx+parent->pt2px(painter, tickOutsideLength+tickLabelDistance);
|
|
if (tickLabelAngle==90) {
|
|
painter.save();
|
|
painter.translate(lx+descent, yy-width/2.0);
|
|
painter.rotate(tickLabelAngle);
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else if (tickLabelAngle==-90) {
|
|
painter.save();
|
|
painter.translate(lx+ascent, yy+width/2.0);
|
|
painter.rotate(tickLabelAngle);
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
double shiftx=0;
|
|
if (tickLabelAngle>0) {
|
|
shiftx=strikeoutPos*sin(fabs(tickLabelAngle)/180.0*M_PI);
|
|
} else {
|
|
|
|
}
|
|
painter.translate(lx+shiftx, yy+strikeoutPos);
|
|
painter.rotate(-tickLabelAngle);
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, lx, yy+strikeoutPos);
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPverticalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
|
|
|
|
// 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 (get_parent_otheraxis_inverted()) {
|
|
left=get_parent_otheraxis_offset()-get_parent_otheraxis_width();//;
|
|
right=get_parent_otheraxis_offset();//;
|
|
} else {
|
|
left=get_parent_otheraxis_offset();//;
|
|
right=get_parent_otheraxis_offset()+get_parent_otheraxis_width();//;
|
|
}
|
|
//qDebug()<<"JKQTPverticalAxis:";
|
|
//qDebug()<<" left="<<left;
|
|
//qDebug()<<" right="<<right;
|
|
//qDebug()<<" top="<<top;
|
|
//qDebug()<<" bottom="<<bottom;
|
|
//qDebug()<<" scale="<<scale;
|
|
//qDebug()<<" offset="<<offset;
|
|
//qDebug()<<" x2p(0)="<<x2p(0);
|
|
//qDebug()<<" tickStart="<<tickStart;
|
|
|
|
if (std::isnan(left) || std::isnan(right) || std::isnan(top) || std::isnan(bottom)) return;
|
|
if (std::isinf(left) || std::isinf(right) || std::isinf(top) || std::isinf(bottom)) return;
|
|
//qDebug()<<" start JKQTPverticalAxis::drawAxes(";
|
|
//qDebug()<<"drawing vertical axis ... range = ["<<axismin<<" .. "<<axismax<<"]\n";
|
|
|
|
painter.save();
|
|
QPen pmain=painter.pen();
|
|
pmain.setColor(axisColor);
|
|
pmain.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, lineWidth*parent->get_lineWidthMultiplier())));
|
|
pmain.setStyle(Qt::SolidLine);
|
|
|
|
QPen ptick=pmain;
|
|
ptick.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, tickWidth*parent->get_lineWidthMultiplier())));
|
|
|
|
QPen pmtick=ptick;
|
|
pmtick.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, minorTickWidth*parent->get_lineWidthMultiplier())));
|
|
|
|
get_parent_mathText()->set_fontSize(tickLabelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
painter.setPen(pmain);
|
|
|
|
// plot thick axis at y==0
|
|
if (showZeroAxis && (0>axismin) && (0<axismax)) {
|
|
QPen pmain1=pmain;
|
|
pmain1.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, lineWidthZeroAxis*parent->get_lineWidthMultiplier())));
|
|
painter.setPen(pmain1);
|
|
QLineF l(left-parent->pt2px(painter, tickOutsideLength), x2p(0), right+parent->pt2px(painter, tickOutsideLength), x2p(0));
|
|
painter.drawLine(l);
|
|
|
|
painter.setPen(pmain);
|
|
}
|
|
|
|
// draw thick axis lines, left and/or right
|
|
if (drawMode1!=JKQTPCADMnone) {
|
|
QLineF l(left, x2p(axismin), left, x2p(axismax));
|
|
painter.drawLine(l);
|
|
}
|
|
if (drawMode2!=JKQTPCADMnone) {
|
|
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<QLineF> lines_ptick, lines_ptick2;
|
|
QVector<QLineF> lines_pmtick, lines_pmtick2;
|
|
|
|
|
|
while (getNextLabel(x, label, first) && cnt<200) {
|
|
double mtdist=getNextLabelDistance(x)/(double)(minorTicks+1);
|
|
|
|
double xleft=-1000000;
|
|
double xx=x2p(x);
|
|
//qDebug()<<" tick @ x="<<x<<" label="<<label<<" mtdist="<<mtdist<<" minorTicks="<<minorTicks;
|
|
|
|
if (drawMode1==JKQTPCADMticks || drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete) {
|
|
//painter.setPen(ptick);
|
|
if ((x<=axismax) && (x>=axismin)) {
|
|
QLineF l(left-parent->pt2px(painter, tickOutsideLength), xx, left+parent->pt2px(painter, tickInsideLength), xx);
|
|
if (l.length()>0) lines_ptick.append(l);//painter.drawLine(l);
|
|
}
|
|
//painter.setPen(pmtick);
|
|
if ((tickLabels.size()<=0) && (minorTicks>0)) {
|
|
double mx=x+mtdist;
|
|
int minTickCnt=minorTicks;
|
|
if (isLogAxis()) {
|
|
if (mtdist>x) {
|
|
mx=mtdist;
|
|
} else {
|
|
minTickCnt--;
|
|
mx=2.0*mtdist;
|
|
}
|
|
|
|
}
|
|
for (int i=0; i<minTickCnt; i++) {
|
|
double mxx=x2p(mx);
|
|
//if (logAxis) qDebug()<<i<<" => "<<mx<<mxx<<apprLogTicks<<w<<minorTicks;
|
|
if (mx<=axismax && mx>=axismin) {
|
|
QLineF l(xleft=left-parent->pt2px(painter, minorTickOutsideLength), mxx, left+parent->pt2px(painter, minorTickInsideLength), mxx);
|
|
if (l.length()>0) lines_pmtick.append(l);//painter.drawLine(l);
|
|
double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase)));
|
|
|
|
if (minorTickLabelsEnabled) {
|
|
if (minorTickLabelFullNumber) val=mx;
|
|
QString minorlabel=floattolabel(val);
|
|
drawTickLabel1(painter, left, mxx, minorlabel, minorTickLabelFontSize);
|
|
//drawTickLabel2(painter, right, xx, minorlabel, minorTickLabelFontSize);
|
|
}
|
|
}
|
|
mx=mx+mtdist;
|
|
|
|
}
|
|
}
|
|
}
|
|
if (drawMode2==JKQTPCADMticks || drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete) {
|
|
//painter.setPen(ptick);
|
|
if (x<=axismax && x>=axismin) {
|
|
QLineF l(right-parent->pt2px(painter, tickInsideLength), xx, right+parent->pt2px(painter, tickOutsideLength), xx);
|
|
if (l.length()>0) lines_ptick2.append(l);//painter.drawLine(l);
|
|
}
|
|
//painter.setPen(pmtick);
|
|
if ((tickLabels.size()<=0) && (minorTicks>0)) {
|
|
double mx=x+mtdist;
|
|
int minTickCnt=minorTicks;
|
|
if (isLogAxis()) {
|
|
if (mtdist>x) {
|
|
mx=mtdist;
|
|
} else {
|
|
minTickCnt--;
|
|
mx=2.0*mtdist;
|
|
}
|
|
|
|
}
|
|
for (int i=0; i<minTickCnt; i++) {
|
|
double mxx=x2p(mx);
|
|
if (mx<=axismax && mx>=axismin) {
|
|
QLineF l(right-parent->pt2px(painter, minorTickInsideLength), mxx, xleft=(right+parent->pt2px(painter, minorTickOutsideLength)), mxx);
|
|
if (l.length()>0) lines_pmtick2.append(l);//painter.drawLine(l);
|
|
double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase)));
|
|
|
|
if (minorTickLabelsEnabled) {
|
|
if (minorTickLabelFullNumber) val=mx;
|
|
QString minorlabel=floattolabel(val);
|
|
//drawTickLabel1(painter, left, xx, minorlabel, minorTickLabelFontSize);
|
|
drawTickLabel2(painter, xleft, mxx, minorlabel, minorTickLabelFontSize);
|
|
}
|
|
}
|
|
mx=mx+mtdist;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((label!="") && (x<=axismax && x>=axismin) && (drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete || drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete)) {
|
|
|
|
|
|
drawTickLabel1(painter, left, xx, label, tickLabelFontSize);
|
|
drawTickLabel2(painter, right, xx, label, tickLabelFontSize);
|
|
|
|
}
|
|
first=false;
|
|
cnt++;
|
|
}
|
|
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() && (drawMode1==JKQTPCADMcomplete)) {
|
|
get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
|
|
|
|
QRect rect(0,0, get_parent_plotwidth(), ascent+descent);//plotBorderLeft-30);
|
|
painter.save();
|
|
painter.translate(QPointF(left-parent->pt2px(painter, tickOutsideLength+tickLabelDistance+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(labelPosition) {
|
|
case JKQTPlabelMax:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect);
|
|
break;
|
|
case JKQTPlabelMin:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect);
|
|
break;
|
|
case JKQTPlabelCenter:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect);
|
|
break;
|
|
}
|
|
painter.resetTransform();
|
|
painter.restore();
|
|
}
|
|
if (!axisLabel.isEmpty() && (drawMode2==JKQTPCADMcomplete)) {
|
|
get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
|
|
|
|
QRect rect(0,0, get_parent_plotwidth(), get_parent_mathText()->getSize(painter).height());//plotBorderLeft-30);
|
|
painter.save();
|
|
painter.translate(QPointF(right+parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+labelMax.width(), bottom));
|
|
painter.rotate(-90);
|
|
//JKQTPEnhancedPainter::RenderHints h=painter.renderHints();
|
|
//painter.drawRect(rect);
|
|
//painter.drawEllipse(-4, -4, 8, 8);
|
|
switch(labelPosition) {
|
|
case JKQTPlabelMax:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect);
|
|
break;
|
|
case JKQTPlabelMin:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect);
|
|
break;
|
|
case JKQTPlabelCenter:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect);
|
|
break;
|
|
}
|
|
//painter.resetTransform();
|
|
painter.restore();
|
|
}
|
|
painter.restore();
|
|
//qDebug()<<" end JKQTPverticalAxis::drawAxes(";
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPverticalIndependentAxis::JKQTPverticalIndependentAxis(double axisOffset, double axisWidth, double otherAxisOffset, double otherAxisWidth, JKQtBasePlotter* parent):
|
|
JKQTPverticalAxis(parent)
|
|
{
|
|
this->axisOffset=axisOffset;
|
|
this->axisWidth=axisWidth;
|
|
this->otherAxisOffset=otherAxisOffset;
|
|
this->otherAxisWidth=otherAxisWidth;
|
|
this->otherAxisInverted=false;
|
|
}
|
|
|
|
void JKQTPverticalIndependentAxis::set_axisOffset(double __value) {
|
|
this->axisOffset = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPverticalIndependentAxis::set_axisWidth(double __value) {
|
|
this->axisWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPverticalIndependentAxis::set_otherAxisOffset(double __value) {
|
|
this->otherAxisOffset = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPverticalIndependentAxis::set_otherAxisWidth(double __value) {
|
|
this->otherAxisWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPverticalIndependentAxis::set_otherAxisInverted(bool __value) {
|
|
this->otherAxisInverted = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPhorizontalAxis::JKQTPhorizontalAxis(JKQtBasePlotter* parent):
|
|
JKQTPcoordinateAxis(parent)
|
|
{
|
|
//axisPrefix="xaxis_";
|
|
scaleSign=1;
|
|
}
|
|
|
|
double JKQTPhorizontalAxis::get_parent_plotwidth() const {
|
|
return parent->get_plotWidth();
|
|
}
|
|
|
|
double JKQTPhorizontalAxis::get_parent_plotoffset() const {
|
|
return parent->get_iplotBorderLeft();
|
|
}
|
|
|
|
QSize JKQTPhorizontalAxis::getSize1(JKQTPEnhancedPainter& painter) {
|
|
if (drawMode1==JKQTPCADMnone || drawMode1==JKQTPCADMline) return QSize(get_parent_plotwidth(), 0);
|
|
if (drawMode1==JKQTPCADMticks) return QSize(get_parent_plotwidth(), parent->pt2px(painter, tickOutsideLength));
|
|
// find out the maximum width over all visible plot labels
|
|
double tlwidth=getMaxTickLabelSize(painter).height();
|
|
if (drawMode1==JKQTPCADMticksAndLabels) return QSize(get_parent_plotwidth(),parent->pt2px(painter, tickOutsideLength+tickLabelDistance)+tlwidth);
|
|
|
|
// find out size of axis label
|
|
/*get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double lwidth=get_parent_mathText()->getSize(painter).height();*/
|
|
double lwidth=parent->getTextSizeSize(labelFont, labelFontSize*parent->get_fontSizeMultiplier(), axisLabel, painter).height();
|
|
|
|
if (drawMode1==JKQTPCADMcomplete) return QSize(get_parent_plotwidth(),parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+tlwidth+lwidth);
|
|
|
|
return QSize(0,0);
|
|
}
|
|
|
|
QSize JKQTPhorizontalAxis::getSize2(JKQTPEnhancedPainter& painter) {
|
|
if (drawMode2==JKQTPCADMnone || drawMode2==JKQTPCADMline) return QSize(get_parent_plotwidth(), 0);
|
|
if (drawMode2==JKQTPCADMticks) return QSize(get_parent_plotwidth(), parent->pt2px(painter, tickOutsideLength));
|
|
// find out the maximum width over all visible plot labels
|
|
double tlwidth=getMaxTickLabelSize(painter).height();
|
|
if (drawMode2==JKQTPCADMticksAndLabels) return QSize(get_parent_plotwidth(),parent->pt2px(painter, tickOutsideLength+tickLabelDistance)+tlwidth);
|
|
|
|
// find out size of axis label
|
|
/*get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double lwidth=get_parent_mathText()->getSize(painter).height();*/
|
|
double lwidth=parent->getTextSizeSize(labelFont, labelFontSize*parent->get_fontSizeMultiplier(), axisLabel, painter).height();
|
|
if (drawMode2==JKQTPCADMcomplete) return QSize(get_parent_plotwidth(),parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+tlwidth+lwidth);
|
|
|
|
return QSize(0,0);
|
|
}
|
|
|
|
|
|
double JKQTPhorizontalAxis::get_parent_otheraxis_offset() const {
|
|
return parent->y2p(parent->getYMax());
|
|
}
|
|
|
|
|
|
double JKQTPhorizontalAxis::get_parent_otheraxis_width() const {
|
|
return fabs(parent->y2p(parent->getYMax())-parent->y2p(parent->getYMin()));
|
|
}
|
|
|
|
bool JKQTPhorizontalAxis::get_parent_otheraxis_inverted() const
|
|
{
|
|
return parent->getYAxis()->get_inverted();
|
|
}
|
|
|
|
void JKQTPhorizontalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
|
|
painter.save();
|
|
//double right=x2p(axismax);
|
|
//double left=x2p(axismin);
|
|
double bottom=0;
|
|
double top=0;
|
|
if (get_parent_otheraxis_inverted()) {
|
|
top=get_parent_otheraxis_offset()-get_parent_otheraxis_width();//;
|
|
bottom=get_parent_otheraxis_offset();//;
|
|
} else {
|
|
top=get_parent_otheraxis_offset();//;
|
|
bottom=get_parent_otheraxis_offset()+get_parent_otheraxis_width();//;
|
|
}
|
|
QPen pg=painter.pen();
|
|
pg.setColor(gridColor);
|
|
pg.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, gridWidth*parent->get_fontSizeMultiplier())));
|
|
pg.setStyle(gridStyle);
|
|
QPen pmg=painter.pen();
|
|
pmg.setColor(minorGridColor);
|
|
pmg.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, minorGridWidth*parent->get_lineWidthMultiplier())));
|
|
pmg.setStyle(minorGridStyle);
|
|
|
|
double x=tickStart;
|
|
QString label="";
|
|
bool first=true;
|
|
// loop through all labels, as they are at the major ticks
|
|
int cnt=0;
|
|
QVector<QLineF> lines_pg;
|
|
QVector<QLineF> lines_pmg;
|
|
|
|
while (getNextLabel(x, label, first) && cnt<200) {
|
|
double mtdist=getNextLabelDistance(x)/(double)(minorTicks+1);
|
|
|
|
double xx=x2p(x);
|
|
//qDebug()<<" tick @ x="<<x<<" label="<<label<<" mtdist="<<mtdist<<" minorTicks="<<minorTicks;
|
|
|
|
//painter.setPen(pg);
|
|
if (drawGrid && (x<axismax) && (x>axismin)) {
|
|
QLineF l(xx, bottom, xx, top);
|
|
if (l.length()>0) lines_pg.append(l);//painter.drawLine(l);
|
|
}
|
|
//painter.setPen(pmg);
|
|
if ((tickLabels.size()<=0) && drawMinorGrid && (minorTicks>0)) {
|
|
double mx=x+mtdist;
|
|
for (int i=0; i<(int)minorTicks; i++) {
|
|
double mxx=x2p(mx);
|
|
if ((mx<axismax) && (mx>axismin)) {
|
|
QLineF l( mxx, bottom, mxx, top);
|
|
if (l.length()>0) lines_pmg.append(l);//painter.drawLine(l);
|
|
}
|
|
mx=mx+mtdist;
|
|
}
|
|
}
|
|
first=false;
|
|
cnt++;
|
|
}
|
|
painter.setPen(pg);
|
|
painter.drawLines(lines_pg);
|
|
painter.setPen(pmg);
|
|
painter.drawLines(lines_pmg);
|
|
painter.restore();
|
|
}
|
|
|
|
|
|
void JKQTPhorizontalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, const QString &label, double fontSize, double ascentMax, double /*descentMax*/)
|
|
{
|
|
get_parent_mathText()->set_fontSize(fontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
get_parent_mathText()->parse(label);
|
|
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
if (drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete) {
|
|
double lx0=yy+parent->pt2px(painter, tickOutsideLength+tickLabelDistance);
|
|
double lx=lx0+ascentMax;
|
|
if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
if (tickLabelAngle>0) {
|
|
painter.translate(xx-fabs(ascent*sin(tickLabelAngle/180.0*M_PI)/2.0), lx0+fabs(ascent*cos(tickLabelAngle/180.0*M_PI)));
|
|
painter.rotate(tickLabelAngle);
|
|
} else {
|
|
painter.translate(xx+fabs(ascent*sin(fabs(tickLabelAngle)/180.0*M_PI)/2.0)-width*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI)), lx0+ascent*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI))+fabs(width*sin(fabs(tickLabelAngle)/180.0*M_PI)));
|
|
painter.rotate(tickLabelAngle);
|
|
}
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, xx-width/2.0, lx);
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPhorizontalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, const QString &label, double fontSize, double /*ascentMax*/, double descentMax)
|
|
{
|
|
get_parent_mathText()->set_fontSize(fontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
get_parent_mathText()->parse(label);
|
|
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
if (drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete) {
|
|
double lx0=yy-parent->pt2px(painter, tickOutsideLength+tickLabelDistance);
|
|
double lx=lx0-descentMax;
|
|
if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
if (tickLabelAngle>0) {
|
|
painter.translate(xx+fabs(descent*sin(tickLabelAngle/180.0*M_PI)/2.0), lx0-fabs(descent*cos(tickLabelAngle/180.0*M_PI)));
|
|
painter.rotate(-tickLabelAngle);
|
|
} else {
|
|
painter.translate(xx-fabs(descent*sin(fabs(tickLabelAngle)/180.0*M_PI)/2.0)-width*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI)), lx0-descent*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI))-fabs(width*sin(fabs(tickLabelAngle)/180.0*M_PI)));
|
|
painter.rotate(-tickLabelAngle);
|
|
}
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, xx-width/2.0, lx);
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
void JKQTPhorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
|
|
|
|
// make shure all parameters are calculated correctly
|
|
calcPlotScaling();
|
|
|
|
// determine pixel coordinates of important positions
|
|
double right=x2p(axismax);
|
|
double left=x2p(axismin);
|
|
double bottom=0;
|
|
double top=0;
|
|
if (inverted) {
|
|
qSwap(left, right);
|
|
}
|
|
if (get_parent_otheraxis_inverted()) {
|
|
top=get_parent_otheraxis_offset()-get_parent_otheraxis_width();//;
|
|
bottom=get_parent_otheraxis_offset();//;
|
|
} else {
|
|
top=get_parent_otheraxis_offset();//;
|
|
bottom=get_parent_otheraxis_offset()+get_parent_otheraxis_width();//;
|
|
}
|
|
|
|
//qDebug()<<" left="<<left<<"\n";
|
|
//qDebug()<<" right="<<right<<"\n";
|
|
//qDebug()<<" top="<<top<<"\n";
|
|
//qDebug()<<" bottom="<<bottom<<"\n";
|
|
//qDebug()<<" scale="<<scale<<"\n";
|
|
//qDebug()<<" offset="<<offset<<"\n";
|
|
//qDebug()<<" x2p(0)="<<x2p(0);
|
|
//qDebug()<<" tickStart="<<tickStart<<"\n";
|
|
|
|
if (std::isnan(left) || std::isnan(right) || std::isnan(top) || std::isnan(bottom)) return;
|
|
if (std::isinf(left) || std::isinf(right) || std::isinf(top) || std::isinf(bottom)) return;
|
|
//qDebug()<<"drawing vertical axis ... range = ["<<axismin<<" .. "<<axismax<<"]\n";
|
|
|
|
painter.save();
|
|
|
|
QPen pmain=painter.pen();
|
|
pmain.setColor(axisColor);
|
|
pmain.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, lineWidth*parent->get_lineWidthMultiplier())));
|
|
pmain.setStyle(Qt::SolidLine);
|
|
|
|
QPen ptick=pmain;
|
|
ptick.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, tickWidth*parent->get_lineWidthMultiplier())));
|
|
|
|
QPen pmtick=ptick;
|
|
pmtick.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, parent->pt2px(painter, minorTickWidth*parent->get_lineWidthMultiplier())));
|
|
|
|
get_parent_mathText()->set_fontSize(tickLabelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(tickLabelFont);
|
|
get_parent_mathText()->set_fontColor(axisColor);
|
|
|
|
painter.setPen(pmain);
|
|
|
|
// plot thick axis at y==0
|
|
if (showZeroAxis && (0>axismin) && (0<axismax)) {
|
|
QLineF l(x2p(0), bottom+parent->pt2px(painter, tickOutsideLength), x2p(0), top-parent->pt2px(painter, tickOutsideLength));
|
|
painter.drawLine(l);
|
|
}
|
|
|
|
// draw thick axis lines, left and/or right
|
|
if (drawMode1!=JKQTPCADMnone) {
|
|
QLineF l(x2p(axismin), bottom, x2p(axismax), bottom);
|
|
painter.drawLine(l);
|
|
}
|
|
if (drawMode2!=JKQTPCADMnone) {
|
|
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<QLineF> lines_ptick, lines_ptick2;
|
|
QVector<QLineF> lines_pmtick, lines_pmtick2;
|
|
|
|
|
|
while (getNextLabel(x, label, first) && cnt<200) {
|
|
double mtdist=getNextLabelDistance(x)/(double)(minorTicks+1);
|
|
|
|
double xleft=-1000000;
|
|
double xx=x2p(x);
|
|
//qDebug()<<" tick @ x="<<x<<" label="<<label<<" mtdist="<<mtdist<<" minorTicks="<<minorTicks;
|
|
|
|
if (drawMode1==JKQTPCADMticks || drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete) {
|
|
//painter.setPen(ptick);
|
|
if (x<=axismax && x>=axismin) {
|
|
QLineF l(xx, bottom-parent->pt2px(painter, tickInsideLength), xx, bottom+parent->pt2px(painter, tickOutsideLength));
|
|
if (l.length()>0) lines_ptick.append(l);//painter.drawLine(l);
|
|
}
|
|
//painter.setPen(pmtick);
|
|
if ((tickLabels.size()<=0) && (minorTicks>0)) {
|
|
double mx=x+mtdist;
|
|
int minTickCnt=minorTicks;
|
|
if (isLogAxis()) {
|
|
if (mtdist>x) {
|
|
mx=mtdist;
|
|
} else {
|
|
minTickCnt--;
|
|
mx=2.0*mtdist;
|
|
}
|
|
|
|
}
|
|
for (int i=0; i<minTickCnt; i++) {
|
|
double mxx=x2p(mx);
|
|
|
|
if (mx<=axismax && mx>=axismin) {
|
|
QLineF l( mxx, bottom-parent->pt2px(painter, minorTickInsideLength), mxx, xleft=(bottom+parent->pt2px(painter, minorTickOutsideLength)));
|
|
if (l.length()>0) lines_pmtick.append(l);//painter.drawLine(l);
|
|
|
|
double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase)));
|
|
|
|
if (minorTickLabelsEnabled) {
|
|
if (minorTickLabelFullNumber) val=mx;
|
|
QString minorlabel=floattolabel(val);
|
|
drawTickLabel1(painter, mxx, xleft, minorlabel, minorTickLabelFontSize, ascentMax, descentMax);
|
|
//drawTickLabel2(painter, right, xx, minorlabel, minorTickLabelFontSize, ascentMax, descentMax);
|
|
}
|
|
|
|
/*double val= mx/pow(10.0,floor(log10(mx)));
|
|
if (isLogAxis() && minorTickLabelsEnabled && apprLogTicks<=2 && val>1.05) {
|
|
painter.save();
|
|
QFont f;
|
|
f.setFamily(tickLabelFont);
|
|
f.setPointSizeF(minorTickLabelFontSize*parent->get_fontSizeMultiplier());
|
|
painter.setFont(f);
|
|
painter.setPen(axisColor);
|
|
QFontMetrics fm(f);
|
|
QString str=QString::number(val);
|
|
double wid=fm.width(str);
|
|
double heig=fm.ascent();
|
|
painter.drawText(QPointF(mxx-wid/2.0, xleft+parent->pt2px(painter, minorTickOutsideLength)/2.0+heig), str);
|
|
painter.restore();
|
|
}*/
|
|
}
|
|
mx=mx+mtdist;
|
|
}
|
|
}
|
|
}
|
|
if (drawMode2==JKQTPCADMticks || drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete) {
|
|
painter.setPen(ptick);
|
|
if (x<=axismax && x>=axismin) {
|
|
QLineF l(xx, top-parent->pt2px(painter, tickOutsideLength), xx, top+parent->pt2px(painter, tickInsideLength));
|
|
if (l.length()>0) lines_ptick2.append(l);//painter.drawLine(l);
|
|
}
|
|
painter.setPen(pmtick);
|
|
if ((tickLabels.size()<=0) && (minorTicks>0)) {
|
|
double mx=x+mtdist;
|
|
int minTickCnt=minorTicks;
|
|
if (isLogAxis()) {
|
|
if (mtdist>x) {
|
|
mx=mtdist;
|
|
} else {
|
|
minTickCnt--;
|
|
mx=2.0*mtdist;
|
|
}
|
|
|
|
}
|
|
for (int i=0; i<minTickCnt; i++) {
|
|
double mxx=x2p(mx);
|
|
if (mx<=axismax && mx>=axismin) {
|
|
QLineF l( mxx, top-parent->pt2px(painter, minorTickOutsideLength), mxx, xleft=(top+parent->pt2px(painter, minorTickInsideLength)));
|
|
if (l.length()>0) lines_pmtick2.append(l);//painter.drawLine(l);
|
|
|
|
double val= mx/pow(logAxisBase,floor(log(mx)/log(logAxisBase)));
|
|
|
|
if (minorTickLabelsEnabled) {
|
|
if (minorTickLabelFullNumber) val=mx;
|
|
QString minorlabel=floattolabel(val);
|
|
drawTickLabel2(painter, mxx, xleft, minorlabel, minorTickLabelFontSize, ascentMax, descentMax);
|
|
//drawTickLabel2(painter, right, xx, minorlabel, minorTickLabelFontSize, ascentMax, descentMax);
|
|
}
|
|
|
|
/*
|
|
double val= mx/pow(10.0,floor(log10(mx)));
|
|
if (isLogAxis() && minorTickLabelsEnabled && apprLogTicks<=2 && val>1.05) {
|
|
painter.save();
|
|
QFont f;
|
|
f.setFamily(tickLabelFont);
|
|
f.setPointSizeF(minorTickLabelFontSize*parent->get_fontSizeMultiplier());
|
|
painter.setFont(f);
|
|
painter.setPen(axisColor);
|
|
QFontMetrics fm(f);
|
|
QString str=QString::number(val);
|
|
double wid=fm.width(str);
|
|
double heig=fm.ascent();
|
|
painter.drawText(QPointF(mxx-wid/2.0, xleft-parent->pt2px(painter, minorTickOutsideLength)/2.0), str);
|
|
painter.restore();
|
|
}*/
|
|
}
|
|
mx=mx+mtdist;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((label!="") && (x<=axismax && x>=axismin) && (drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete || drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete)) {
|
|
|
|
|
|
drawTickLabel1(painter, xx, bottom, label, tickLabelFontSize, ascentMax, descentMax);
|
|
drawTickLabel2(painter, xx, top, label, tickLabelFontSize, ascentMax, descentMax);
|
|
|
|
/*
|
|
get_parent_mathText()->parse(label);
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
if (drawMode1==JKQTPCADMticksAndLabels || drawMode1==JKQTPCADMcomplete) {
|
|
double lx0=bottom+parent->pt2px(painter, tickOutsideLength+tickLabelDistance);
|
|
double lx=lx0+ascentMax;
|
|
if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
if (tickLabelAngle>0) {
|
|
painter.translate(xx-fabs(ascent*sin(tickLabelAngle/180.0*M_PI)/2.0), lx0+fabs(ascent*cos(tickLabelAngle/180.0*M_PI)));
|
|
painter.rotate(tickLabelAngle);
|
|
} else {
|
|
painter.translate(xx+fabs(ascent*sin(fabs(tickLabelAngle)/180.0*M_PI)/2.0)-width*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI)), lx0+ascent*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI))+fabs(width*sin(fabs(tickLabelAngle)/180.0*M_PI)));
|
|
painter.rotate(tickLabelAngle);
|
|
}
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, xx-width/2.0, lx);
|
|
}
|
|
}
|
|
if (drawMode2==JKQTPCADMticksAndLabels || drawMode2==JKQTPCADMcomplete) {
|
|
double lx0=top-parent->pt2px(painter, tickOutsideLength+tickLabelDistance);
|
|
double lx=lx0-descentMax;
|
|
if (tickLabelAngle!=0) {
|
|
painter.save();
|
|
if (tickLabelAngle>0) {
|
|
painter.translate(xx+fabs(descent*sin(tickLabelAngle/180.0*M_PI)/2.0), lx0-fabs(descent*cos(tickLabelAngle/180.0*M_PI)));
|
|
painter.rotate(-tickLabelAngle);
|
|
} else {
|
|
painter.translate(xx-fabs(descent*sin(fabs(tickLabelAngle)/180.0*M_PI)/2.0)-width*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI)), lx0-descent*fabs(cos(fabs(tickLabelAngle)/180.0*M_PI))-fabs(width*sin(fabs(tickLabelAngle)/180.0*M_PI)));
|
|
painter.rotate(-tickLabelAngle);
|
|
}
|
|
get_parent_mathText()->draw(painter, 0,0);
|
|
painter.restore();
|
|
} else {
|
|
get_parent_mathText()->draw(painter, xx-width/2.0, lx);
|
|
}
|
|
|
|
|
|
}*/
|
|
}
|
|
first=false;
|
|
cnt++;
|
|
}
|
|
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() && (drawMode1==JKQTPCADMcomplete)) {
|
|
get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
double width, ascent, descent, strikeoutPos;
|
|
get_parent_mathText()->getSizeDetail(painter, width, ascent, descent, strikeoutPos);
|
|
|
|
|
|
QRect rect(0,0, get_parent_plotwidth(), ascent+descent);//plotBorderLeft-30);
|
|
painter.save();
|
|
painter.translate(QPointF(left, bottom+parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)+labelMax.height()));
|
|
//JKQTPEnhancedPainter::RenderHints h=painter.renderHints();
|
|
//painter.drawRect(rect);
|
|
//painter.drawEllipse(-4, -4, 8, 8);
|
|
switch(labelPosition) {
|
|
case JKQTPlabelMax:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect);
|
|
break;
|
|
case JKQTPlabelMin:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect);
|
|
break;
|
|
case JKQTPlabelCenter:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect);
|
|
break;
|
|
}
|
|
//painter.resetTransform();
|
|
painter.restore();
|
|
}
|
|
if (!axisLabel.isEmpty() && (drawMode2==JKQTPCADMcomplete)) {
|
|
get_parent_mathText()->set_fontSize(labelFontSize*parent->get_fontSizeMultiplier());
|
|
get_parent_mathText()->set_fontRoman(labelFont);
|
|
get_parent_mathText()->parse(axisLabel);
|
|
|
|
|
|
QRect rect(0,0, get_parent_plotwidth(), get_parent_mathText()->getSize(painter).height());//plotBorderLeft-30);
|
|
painter.save();
|
|
painter.translate(QPointF(left, top-parent->pt2px(painter, tickOutsideLength+tickLabelDistance+labelDistance)-labelMax.height()-rect.height()));
|
|
//JKQTPEnhancedPainter::RenderHints h=painter.renderHints();
|
|
//painter.drawRect(rect);
|
|
//painter.drawEllipse(-4, -4, 8, 8);
|
|
switch(labelPosition) {
|
|
case JKQTPlabelMax:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignRight, rect);
|
|
break;
|
|
case JKQTPlabelMin:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignLeft, rect);
|
|
break;
|
|
case JKQTPlabelCenter:
|
|
get_parent_mathText()->draw(painter, Qt::AlignBottom|Qt::AlignHCenter, rect);
|
|
break;
|
|
}
|
|
//painter.resetTransform();
|
|
painter.restore();
|
|
}
|
|
#ifdef SHOW_JKQTPLOTTER_DEBUG
|
|
QPen mp=QPen(QColor("blue"));
|
|
mp.setWidthF(3);
|
|
painter.setPen(mp);
|
|
painter.drawLine(QLineF(get_parent_plotoffset(), top, get_parent_plotoffset()+get_parent_plotwidth(), bottom));
|
|
painter.drawEllipse(QPointF(get_parent_plotoffset(), top), 5,5);
|
|
#endif
|
|
painter.restore();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPhorizontalIndependentAxis::JKQTPhorizontalIndependentAxis(double axisOffset, double axisWidth, double otherAxisOffset, double otherAxisWidth, JKQtBasePlotter* parent):
|
|
JKQTPhorizontalAxis(parent)
|
|
{
|
|
this->axisOffset=axisOffset;
|
|
this->axisWidth=axisWidth;
|
|
this->otherAxisOffset=otherAxisOffset;
|
|
this->otherAxisWidth=otherAxisWidth;
|
|
this->otherAxisInverted=false;
|
|
}
|
|
|
|
void JKQTPhorizontalIndependentAxis::set_axisOffset(double __value) {
|
|
this->axisOffset = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPhorizontalIndependentAxis::set_axisWidth(double __value) {
|
|
this->axisWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPhorizontalIndependentAxis::set_otherAxisOffset(double __value) {
|
|
this->otherAxisOffset = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPhorizontalIndependentAxis::set_otherAxisWidth(double __value) {
|
|
this->otherAxisWidth = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
void JKQTPhorizontalIndependentAxis::set_otherAxisInverted(bool __value) {
|
|
this->otherAxisInverted = __value;
|
|
this->paramsChanged=true;
|
|
update_plot();
|
|
}
|
|
|
|
double JKQTPhorizontalIndependentAxis::get_parent_plotwidth() const { return axisWidth; }
|
|
|
|
double JKQTPhorizontalIndependentAxis::get_parent_plotoffset() const { return axisOffset; }
|
|
|
|
double JKQTPhorizontalIndependentAxis::get_parent_otheraxis_width() const { return otherAxisWidth; }
|
|
|
|
bool JKQTPhorizontalIndependentAxis::get_parent_otheraxis_inverted() const { return otherAxisInverted; }
|
|
|
|
double JKQTPhorizontalIndependentAxis::get_parent_otheraxis_offset() const { return otherAxisOffset; }
|
|
|
|
|