| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
 | 
					
						
							|  |  |  | // written by Christian Daniel                                                   //
 | 
					
						
							| 
									
										
										
										
											2023-11-19 13:31:45 +01:00
										 |  |  | // Copyright (C) 2015, 2017-2019, 2022 Edouard Griffiths, F4EXB <f4exb06@gmail.com> //
 | 
					
						
							|  |  |  | // Copyright (C) 2022 Jon Beniston, M7RCE <jon@beniston.com>                     //
 | 
					
						
							|  |  |  | // Copyright (C) 2022 Jiří Pinkava <jiri.pinkava@rossum.ai>                      //
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // This program is free software; you can redistribute it and/or modify          //
 | 
					
						
							|  |  |  | // it under the terms of the GNU General Public License as published by          //
 | 
					
						
							|  |  |  | // the Free Software Foundation as version 3 of the License, or                  //
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:43:33 +02:00
										 |  |  | // (at your option) any later version.                                           //
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 General Public License V3 for more details.                               //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU General Public License             //
 | 
					
						
							|  |  |  | // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | 
					
						
							|  |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2022-11-17 14:41:55 +00:00
										 |  |  | #include <QObject>
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | #include <QFontMetrics>
 | 
					
						
							|  |  |  | #include <QDataStream>
 | 
					
						
							|  |  |  | #include "gui/scaleengine.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | static double trunc(double d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (d > 0) ? floor(d) : ceil(d); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | QString ScaleEngine::formatTick(double value, int decimalPlaces) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 	if (m_physicalUnit != Unit::TimeHMS) | 
					
						
							| 
									
										
										
										
											2017-07-22 04:23:10 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |         if (m_physicalUnit == Unit::Scientific) { | 
					
						
							| 
									
										
										
										
											2018-07-08 18:59:09 +02:00
										 |  |  |             return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             return QString("%1%2%3") | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 .arg(m_truncated ? "'" : "") | 
					
						
							|  |  |  |                 .arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces) | 
					
						
							|  |  |  |                 .arg(m_truncated ? m_multiplierStr : ""); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-22 04:23:10 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 	    if (m_scale < 1.0f) { // sub second prints just as is
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |             return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		QString str; | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 		double actual = value * m_scale; // this is the actual value in seconds
 | 
					
						
							|  |  |  | 		double orig = fabs(actual); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		double tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |         if (m_truncated) { | 
					
						
							|  |  |  |             str = "'"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (orig >= 86400.0) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			tmp = floor(actual / 86400.0); | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 			str += QString("%1.").arg(tmp, 0, 'f', 0); | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			actual -= tmp * 86400.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |             if (actual < 0.0) { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			    actual *= -1.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 		if (orig >= 3600.0) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			tmp = floor(actual / 3600.0); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			str += QString("%1:").arg(tmp, 2, 'f', 0, QChar('0')); | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			actual -= tmp * 3600.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (actual < 0.0) { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			    actual *= -1.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 		if (orig >= 60.0) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			tmp = floor(actual / 60.0); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			str += QString("%1:").arg(tmp, 2, 'f', 0, QChar('0')); | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			actual -= tmp * 60.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (actual < 0.0) { | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			    actual *= -1.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 		tmp = m_makeOpposite ? -actual : actual; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		str += QString("%1").arg(tmp, 2, 'f', decimalPlaces, QChar('0')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return str; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::calcCharSize() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	QFontMetricsF fontMetrics(m_font); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(m_orientation == Qt::Vertical) { | 
					
						
							|  |  |  | 		m_charSize = fontMetrics.height(); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		QString str("012345679.,-"); | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		float size; | 
					
						
							|  |  |  | 		float max = 0.0f; | 
					
						
							|  |  |  | 		for(i = 0; i < str.length(); i++) { | 
					
						
							| 
									
										
										
										
											2022-09-25 20:05:09 +02:00
										 |  |  | 			size = fontMetrics.horizontalAdvance(QString(str[i])); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			if(size > max) | 
					
						
							|  |  |  | 				max = size; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		m_charSize = max; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::calcScaleFactor() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 	double median, range, freqBase; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	median = ((rangeMax - rangeMin) / 2.0) + rangeMin; | 
					
						
							|  |  |  | 	range = (rangeMax - rangeMin); | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 	freqBase = (median == 0 ? range : median); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	m_scale = 1.0; | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     m_multiplierStr.clear(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch(m_physicalUnit) { | 
					
						
							|  |  |  | 		case Unit::None: | 
					
						
							| 
									
										
										
										
											2018-07-06 01:34:05 +02:00
										 |  |  | 		case Unit::Scientific: | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			m_unitStr.clear(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Frequency: | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 			if(freqBase < 1000.0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QObject::tr("Hz"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = ""; | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 			} else if(freqBase < 1000000.0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QObject::tr("kHz"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "k"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1000.0; | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 			} else if(freqBase < 1000000000.0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QObject::tr("MHz"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "M"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1000000.0; | 
					
						
							| 
									
										
										
										
											2015-06-21 12:46:47 +02:00
										 |  |  | 			} else if(freqBase < 1000000000000.0){ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QObject::tr("GHz"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "G"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1000000000.0; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("THz"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "T"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1000000000000.0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Information: | 
					
						
							|  |  |  | 			if(median < 1024.0) { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("Bytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = ""; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			} else if(median < 1048576.0) { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("KiBytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "k"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1024.0; | 
					
						
							|  |  |  | 			} else if(median < 1073741824.0) { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("MiBytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "M"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1048576.0; | 
					
						
							|  |  |  | 			} else if(median < 1099511627776.0) { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("GiBytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "G"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1073741824.0; | 
					
						
							|  |  |  | 			} else if(median < 1125899906842624.0) { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("TiBytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "T"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1099511627776.0; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				m_unitStr = QObject::tr("PiBytes"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "P"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 1125899906842624.0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Percent: | 
					
						
							|  |  |  | 			m_unitStr = QString("%"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Decibel: | 
					
						
							|  |  |  | 			m_unitStr = QString("dB"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 		case Unit::SUnits: | 
					
						
							|  |  |  | 			m_unitStr = QString("S"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		case Unit::DecibelMilliWatt: | 
					
						
							|  |  |  | 			m_unitStr = QString("dBm"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::DecibelMicroVolt: | 
					
						
							|  |  |  | 			m_unitStr = QString("dBµV"); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::AngleDegrees: | 
					
						
							|  |  |  | 			m_unitStr = QString("°"); | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Time: | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  |         case Unit::TimeHMS: | 
					
						
							|  |  |  | 			if (median < 0.001) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QString("µs"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "µ"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 0.000001; | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			} else if (median < 1.0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QString("ms"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "m"; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_scale = 0.001; | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			} else if (median < 1000.0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_unitStr = QString("s"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = ""; | 
					
						
							| 
									
										
										
										
											2018-07-01 04:10:36 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |                 m_unitStr = QString("ks"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "k"; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |                 m_scale = 1000.0; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case Unit::Volt: | 
					
						
							|  |  |  | 			if (median < 1e-9) { | 
					
						
							|  |  |  | 				m_unitStr = QString("pV"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "p"; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 				m_scale = 1e-12; | 
					
						
							|  |  |  | 			} else if (median < 1e-6) { | 
					
						
							|  |  |  | 				m_unitStr = QString("nV"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "n"; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 				m_scale = 1e-9; | 
					
						
							|  |  |  | 			} else if (median < 1e-3) { | 
					
						
							|  |  |  | 				m_unitStr = QString("µV"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "µ"; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 				m_scale = 1e-6; | 
					
						
							|  |  |  | 			} else if (median < 1.0) { | 
					
						
							|  |  |  | 				m_unitStr = QString("mV"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = "m"; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 				m_scale = 1e-3; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				m_unitStr = QString("V"); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |                 m_multiplierStr = ""; | 
					
						
							| 
									
										
										
										
											2015-07-06 09:17:51 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double ScaleEngine::calcMajorTickUnits(double distance, int* retDecimalPlaces) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	double sign; | 
					
						
							|  |  |  | 	double log10x; | 
					
						
							|  |  |  | 	double exponent; | 
					
						
							|  |  |  | 	double base; | 
					
						
							|  |  |  | 	int decimalPlaces; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(distance == 0.0) | 
					
						
							|  |  |  | 		return 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sign = (distance > 0.0) ? 1.0 : -1.0; | 
					
						
							|  |  |  | 	log10x = log10(fabs(distance)); | 
					
						
							|  |  |  | 	exponent = floor(log10x); | 
					
						
							|  |  |  | 	base = pow(10.0, log10x - exponent); | 
					
						
							|  |  |  | 	decimalPlaces = (int)(-exponent); | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | 	if((m_physicalUnit == Unit::Time) && (distance >= 1.0)) { | 
					
						
							|  |  |  | 		if(retDecimalPlaces != NULL) | 
					
						
							|  |  |  | 			*retDecimalPlaces = 0; | 
					
						
							|  |  |  | 		if(distance < 1.0) | 
					
						
							|  |  |  | 			return 1.0; | 
					
						
							|  |  |  | 		else if(distance < 5.0) | 
					
						
							|  |  |  | 			return 5.0; | 
					
						
							|  |  |  | 		else if(distance < 10.0) | 
					
						
							|  |  |  | 			return 10.0; | 
					
						
							|  |  |  | 		else if(distance < 15.0) | 
					
						
							|  |  |  | 			return 15.0; | 
					
						
							|  |  |  | 		else if(distance < 30.0) | 
					
						
							|  |  |  | 			return 30.0; | 
					
						
							|  |  |  | 		else if(distance < 60.0) | 
					
						
							|  |  |  | 			return 60.0; | 
					
						
							|  |  |  | 		else if(distance < 5.0 * 60.0) | 
					
						
							|  |  |  | 			return 5.0 * 60.0; | 
					
						
							|  |  |  | 		else if(distance < 10.0 * 60.0) | 
					
						
							|  |  |  | 			return 10.0 * 60.0; | 
					
						
							|  |  |  | 		else if(distance < 15.0 * 60.0) | 
					
						
							|  |  |  | 			return 15.0 * 60.0; | 
					
						
							|  |  |  | 		else if(distance < 30.0 * 60.0) | 
					
						
							|  |  |  | 			return 30.0 * 60.0; | 
					
						
							|  |  |  | 		else if(distance < 3600.0) | 
					
						
							|  |  |  | 			return 3600.0; | 
					
						
							|  |  |  | 		else if(distance < 2.0 * 3600.0) | 
					
						
							|  |  |  | 			return 2.0 * 3600.0; | 
					
						
							|  |  |  | 		else if(distance < 3.0 * 3600.0) | 
					
						
							|  |  |  | 			return 3.0 * 3600.0; | 
					
						
							|  |  |  | 		else if(distance < 6.0 * 3600.0) | 
					
						
							|  |  |  | 			return 6.0 * 3600.0; | 
					
						
							|  |  |  | 		else if(distance < 12.0 * 3600.0) | 
					
						
							|  |  |  | 			return 12.0 * 3600.0; | 
					
						
							|  |  |  | 		else if(distance < 86000.0) | 
					
						
							|  |  |  | 			return 86000.0; | 
					
						
							|  |  |  | 		else if(distance < 2.0 * 86000.0) | 
					
						
							|  |  |  | 			return 2.0 * 86000.0; | 
					
						
							|  |  |  | 		else if(distance < 7.0 * 86000.0) | 
					
						
							|  |  |  | 			return 7.0 * 86000.0; | 
					
						
							|  |  |  | 		else if(distance < 10.0 * 86000.0) | 
					
						
							|  |  |  | 			return 10.0 * 86000.0; | 
					
						
							|  |  |  | 		else if(distance < 30.0 * 86000.0) | 
					
						
							|  |  |  | 			return 30.0 * 86000.0; | 
					
						
							|  |  |  | 		else return 90.0 * 86000.0; | 
					
						
							| 
									
										
										
										
											2018-07-08 18:59:09 +02:00
										 |  |  | 	} */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(base <= 1.0) { | 
					
						
							|  |  |  |         base = 1.0; | 
					
						
							|  |  |  |     } else if(base <= 2.0) { | 
					
						
							|  |  |  |         base = 2.0; | 
					
						
							|  |  |  |     } else if(base <= 2.5) { | 
					
						
							|  |  |  |         base = 2.5; | 
					
						
							|  |  |  |         if(decimalPlaces >= 0) | 
					
						
							|  |  |  |             decimalPlaces++; | 
					
						
							|  |  |  |     } else if(base <= 5.0) { | 
					
						
							|  |  |  |         base = 5.0; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         base = 10.0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-05 10:40:45 +02:00
										 |  |  | 	if(retDecimalPlaces != 0) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		if(decimalPlaces < 0) | 
					
						
							|  |  |  | 			decimalPlaces = 0; | 
					
						
							|  |  |  | 		*retDecimalPlaces = decimalPlaces; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sign * base * pow(10.0, exponent); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | int ScaleEngine::calcTickTextSize(double distance) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	int tmp; | 
					
						
							|  |  |  | 	int tickLen; | 
					
						
							|  |  |  | 	int decimalPlaces; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	tickLen = 1; | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	tmp = formatTick(rangeMin / m_scale, 0).length(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	if(tmp > tickLen) | 
					
						
							|  |  |  | 		tickLen = tmp; | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	tmp = formatTick(rangeMax / m_scale, 0).length(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	if(tmp > tickLen) | 
					
						
							|  |  |  | 		tickLen = tmp; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | 	calcMajorTickUnits(distance, &decimalPlaces); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-07 02:15:24 +02:00
										 |  |  | 	return tickLen + decimalPlaces + 1; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::forceTwoTicks() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Tick tick; | 
					
						
							|  |  |  | 	QFontMetricsF fontMetrics(m_font); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	m_tickList.clear(); | 
					
						
							|  |  |  | 	tick.major = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	tick.pos = getPosFromValueTrunc(rangeMin); | 
					
						
							|  |  |  | 	tick.text = formatTick(rangeMin / m_scale, m_decimalPlaces); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	tick.textSize = fontMetrics.boundingRect(tick.text).width(); | 
					
						
							|  |  |  | 	if(m_orientation == Qt::Vertical) | 
					
						
							|  |  |  | 		tick.textPos = tick.pos - fontMetrics.ascent() / 2; | 
					
						
							|  |  |  | 	else tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2; | 
					
						
							|  |  |  | 	m_tickList.append(tick); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	tick.pos = getPosFromValueTrunc(rangeMax); | 
					
						
							|  |  |  | 	tick.text = formatTick(rangeMax / m_scale, m_decimalPlaces); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	tick.textSize = fontMetrics.boundingRect(tick.text).width(); | 
					
						
							|  |  |  | 	if(m_orientation == Qt::Vertical) | 
					
						
							|  |  |  | 		tick.textPos = tick.pos - fontMetrics.ascent() / 2; | 
					
						
							|  |  |  | 	else tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2; | 
					
						
							|  |  |  | 	m_tickList.append(tick); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::reCalc() | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (m_physicalUnit == Unit::SUnits) { | 
					
						
							|  |  |  |         reCalcS(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         reCalcStd(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::reCalcStd() | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	float majorTickSize; | 
					
						
							|  |  |  | 	double rangeMinScaled; | 
					
						
							|  |  |  | 	double rangeMaxScaled; | 
					
						
							|  |  |  | 	int maxNumMajorTicks; | 
					
						
							|  |  |  | 	int numMajorTicks; | 
					
						
							|  |  |  | 	int step; | 
					
						
							|  |  |  | 	int skip; | 
					
						
							|  |  |  | 	double value; | 
					
						
							|  |  |  | 	double value2; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 	int j; | 
					
						
							|  |  |  | 	Tick tick; | 
					
						
							|  |  |  | 	float pos; | 
					
						
							|  |  |  | 	QString str; | 
					
						
							|  |  |  | 	QFontMetricsF fontMetrics(m_font); | 
					
						
							|  |  |  | 	float endPos; | 
					
						
							|  |  |  | 	float lastEndPos; | 
					
						
							|  |  |  | 	bool done; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 	if (!m_recalc) { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     updateTruncation(); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	m_recalc = false; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	m_tickList.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	calcScaleFactor(); | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rangeMinScaled = rangeMin / m_scale; | 
					
						
							|  |  |  | 	rangeMaxScaled = rangeMax / m_scale; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	if (m_orientation == Qt::Vertical) | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		maxNumMajorTicks = (int)(m_size / (fontMetrics.lineSpacing() * 1.3f)); | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | 		m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces); | 
					
						
							| 
									
										
										
										
											2018-05-07 02:15:24 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | 		majorTickSize = (calcTickTextSize((rangeMaxScaled - rangeMinScaled) / 20) + 2) * m_charSize; | 
					
						
							| 
									
										
										
										
											2018-05-07 02:15:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 		if (majorTickSize != 0.0) { | 
					
						
							|  |  |  |             maxNumMajorTicks = (int)(m_size / majorTickSize); | 
					
						
							| 
									
										
										
										
											2018-05-07 02:15:24 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |             maxNumMajorTicks = 20; | 
					
						
							| 
									
										
										
										
											2018-05-07 02:15:24 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-05-07 11:33:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces); | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	if (numMajorTicks == 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		forceTwoTicks(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(maxNumMajorTicks > 0) | 
					
						
							|  |  |  | 		m_numMinorTicks = (int)(m_size / (maxNumMajorTicks * fontMetrics.height())); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	else | 
					
						
							|  |  |  |         m_numMinorTicks = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_numMinorTicks < 1) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_numMinorTicks = 0; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	else if (m_numMinorTicks < 2) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_numMinorTicks = 1; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	else if (m_numMinorTicks < 5) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_numMinorTicks = 2; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	else if (m_numMinorTicks < 10) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_numMinorTicks = 5; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	else | 
					
						
							|  |  |  |         m_numMinorTicks = 10; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m_firstMajorTickValue = floor(rangeMinScaled / m_majorTickValueDistance) * m_majorTickValueDistance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	skip = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 	if (rangeMinScaled == rangeMaxScaled) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 	while (true) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_tickList.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		step = 0; | 
					
						
							|  |  |  | 		lastEndPos = -100000000; | 
					
						
							|  |  |  | 		done = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 		for (i = 0; true; i++) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			value = majorTickValue(i); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 			for (j = 1; j < m_numMinorTicks; j++) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				value2 = value + minorTickValue(j); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (value2 < rangeMinScaled) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 					continue; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 if (value2 > rangeMaxScaled) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 pos = getPosFromValueTrunc((value + minorTickValue(j)) * m_scale); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if ((pos >= 0) && (pos < m_size)) | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 					tick.pos = pos; | 
					
						
							|  |  |  | 					tick.major = false; | 
					
						
							|  |  |  | 					tick.textPos = -1; | 
					
						
							|  |  |  | 					tick.textSize = -1; | 
					
						
							|  |  |  | 					tick.text.clear(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_tickList.append(tick); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | 			pos = getPosFromValueTrunc(value * m_scale); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (pos < 0.0) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (pos >= m_size) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			tick.pos = pos; | 
					
						
							|  |  |  | 			tick.major = true; | 
					
						
							|  |  |  | 			tick.textPos = -1; | 
					
						
							|  |  |  | 			tick.textSize = -1; | 
					
						
							|  |  |  | 			tick.text.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 			if (step % (skip + 1) != 0) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				m_tickList.append(tick); | 
					
						
							|  |  |  | 				step++; | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  |             step++; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			str = formatTick(value, m_decimalPlaces); | 
					
						
							|  |  |  | 			tick.text = str; | 
					
						
							|  |  |  | 			tick.textSize = fontMetrics.boundingRect(tick.text).width(); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (m_orientation == Qt::Vertical) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				tick.textPos = pos - fontMetrics.ascent() / 2; | 
					
						
							|  |  |  | 				endPos = tick.textPos + fontMetrics.ascent(); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				tick.textPos = pos - fontMetrics.boundingRect(tick.text).width() / 2; | 
					
						
							|  |  |  | 				endPos = tick.textPos + tick.textSize; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 			if (lastEndPos >= tick.textPos) | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				done = false; | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 				lastEndPos = endPos; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m_tickList.append(tick); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (done) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         skip++; | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// make sure we have at least two major ticks with numbers
 | 
					
						
							|  |  |  | 	numMajorTicks = 0; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < m_tickList.count(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		tick = m_tickList.at(i); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (tick.major) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 			numMajorTicks++; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (numMajorTicks < 2) | 
					
						
							|  |  |  | 		forceTwoTicks(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::reCalcS() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float majorTickSize; | 
					
						
							|  |  |  | 	double rangeMinScaled; | 
					
						
							|  |  |  | 	double rangeMaxScaled; | 
					
						
							|  |  |  | 	int maxNumMajorTicks; | 
					
						
							|  |  |  | 	int numMajorTicks; | 
					
						
							|  |  |  | 	Tick tick; | 
					
						
							|  |  |  | 	QString str; | 
					
						
							|  |  |  | 	QFontMetricsF fontMetrics(m_font); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!m_recalc) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     updateTruncation(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_recalc = false; | 
					
						
							|  |  |  | 	m_tickList.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     calcScaleFactor(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rangeMinScaled = rangeMin / m_scale; | 
					
						
							|  |  |  | 	rangeMaxScaled = rangeMax / m_scale; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (m_orientation == Qt::Vertical) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		maxNumMajorTicks = (int)(m_size / (fontMetrics.lineSpacing() * 1.3f)); | 
					
						
							|  |  |  | 		m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		majorTickSize = (calcTickTextSize((rangeMaxScaled - rangeMinScaled) / 20) + 2) * m_charSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (majorTickSize != 0.0) { | 
					
						
							|  |  |  |             maxNumMajorTicks = (int)(m_size / majorTickSize); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  |             maxNumMajorTicks = 20; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (numMajorTicks == 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		forceTwoTicks(); | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (maxNumMajorTicks > 0) | 
					
						
							|  |  |  | 		m_numMinorTicks = (int)(m_size / (maxNumMajorTicks * fontMetrics.height())); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  |         m_numMinorTicks = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_numMinorTicks < 1) | 
					
						
							|  |  |  | 		m_numMinorTicks = 0; | 
					
						
							|  |  |  | 	else if (m_numMinorTicks < 2) | 
					
						
							|  |  |  | 		m_numMinorTicks = 1; | 
					
						
							|  |  |  | 	else if (m_numMinorTicks < 5) | 
					
						
							|  |  |  | 		m_numMinorTicks = 2; | 
					
						
							|  |  |  | 	else if (m_numMinorTicks < 10) | 
					
						
							|  |  |  | 		m_numMinorTicks = 5; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  |         m_numMinorTicks = 10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	m_firstMajorTickValue = floor(rangeMinScaled / m_majorTickValueDistance) * m_majorTickValueDistance; | 
					
						
							|  |  |  | 	// skip = 0;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (rangeMinScaled == rangeMaxScaled) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rangeMinScaled > -73.0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rangeMaxScaled < -73.0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // qDebug("ScaleEngine::reCalcS: m_numMinorTicks: %d maxNumMajorTicks: %d m_firstMajorTickValue: %le rangeMinScaled: %le rangeMaxScaled: %le",
 | 
					
						
							|  |  |  |     //     m_numMinorTicks, maxNumMajorTicks, m_firstMajorTickValue, rangeMinScaled, rangeMaxScaled);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::vector<double> sVals; | 
					
						
							|  |  |  |     std::vector<double> dbVals; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int nbSVals = ((int) (-73.0 - rangeMinScaled)) / 6; | 
					
						
							|  |  |  |     double sFloor = -73.0 - (double) nbSVals*6; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < nbSVals; i++) { | 
					
						
							|  |  |  |         sVals.push_back(sFloor + 6*i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     sVals.push_back(-73.0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int nbDbVals = ((int) (rangeMaxScaled - -73.0)) / 10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 1; i < nbDbVals; i++) { | 
					
						
							|  |  |  |         dbVals.push_back(-73.0 + 10*i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     truncS(maxNumMajorTicks, sVals, dbVals); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double minTickShiftS = 0.0; | 
					
						
							|  |  |  |     double minTickShiftDb = 0.0; | 
					
						
							|  |  |  |     m_tickList.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_numMinorTicks > 1) && (sVals.size() > 1)) { | 
					
						
							|  |  |  |         minTickShiftS = (sVals[1] - sVals[0]) / m_numMinorTicks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((m_numMinorTicks > 1) && (dbVals.size() > 1)) { | 
					
						
							|  |  |  |         minTickShiftDb = (dbVals[1] - dbVals[0]) / m_numMinorTicks; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto sVal : sVals) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int s = (int) (sVal + 6*9 - -73.0) / 6; | 
					
						
							|  |  |  |         // qDebug("ScaleEngine::reCalcS: S : %le (%d)", sVal, s);
 | 
					
						
							|  |  |  |         tick.pos = getPosFromValue(sVal); | 
					
						
							|  |  |  |         tick.major = true; | 
					
						
							|  |  |  |         tick.textPos = -1; | 
					
						
							|  |  |  |         tick.textSize = -1; | 
					
						
							|  |  |  |         tick.text.clear(); | 
					
						
							|  |  |  |         tick.text = QString("%1").arg(s); | 
					
						
							|  |  |  |         adjustText(fontMetrics, tick); | 
					
						
							|  |  |  |         m_tickList.append(tick); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (s == 9) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (dbVals.size() != 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 tick.pos = getPosFromValue(sVal + minTickShiftDb); | 
					
						
							|  |  |  |                 tick.major = false; | 
					
						
							|  |  |  |                 tick.textPos = -1; | 
					
						
							|  |  |  |                 tick.textSize = -1; | 
					
						
							|  |  |  |                 tick.text.clear(); | 
					
						
							|  |  |  |                 m_tickList.append(tick); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for (int i = 1; i < m_numMinorTicks; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 tick.pos = getPosFromValue(sVal + i*(minTickShiftS / (m_numMinorTicks - 1))); | 
					
						
							|  |  |  |                 tick.major = false; | 
					
						
							|  |  |  |                 tick.textPos = -1; | 
					
						
							|  |  |  |                 tick.textSize = -1; | 
					
						
							|  |  |  |                 tick.text.clear(); | 
					
						
							|  |  |  |                 m_tickList.append(tick); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (auto dbVal : dbVals) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int db = (int) (dbVal - -73.0); | 
					
						
							|  |  |  |         // qDebug("ScaleEngine::reCalcS: dB: %le (+%d)", dbVal, db);
 | 
					
						
							|  |  |  |         tick.pos = getPosFromValue(dbVal); | 
					
						
							|  |  |  |         tick.major = true; | 
					
						
							|  |  |  |         tick.textPos = -1; | 
					
						
							|  |  |  |         tick.textSize = -1; | 
					
						
							|  |  |  |         tick.text.clear(); | 
					
						
							|  |  |  |         tick.text = QString("+%1").arg(db); | 
					
						
							|  |  |  |         adjustText(fontMetrics, tick); | 
					
						
							|  |  |  |         m_tickList.append(tick); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 1; i < m_numMinorTicks; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             tick.pos = getPosFromValue(dbVal + i*(minTickShiftDb / (m_numMinorTicks - 1))); | 
					
						
							|  |  |  |             tick.major = false; | 
					
						
							|  |  |  |             tick.textPos = -1; | 
					
						
							|  |  |  |             tick.textSize = -1; | 
					
						
							|  |  |  |             tick.text.clear(); | 
					
						
							|  |  |  |             m_tickList.append(tick); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::truncS(int nbMaxTicks, std::vector<double>& sVals, std::vector<double>& dbVals) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int nbAvailDb = nbMaxTicks - (int) sVals.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (nbAvailDb <= 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         dbVals.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (nbMaxTicks == (int) sVals.size()) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::vector<double> newSVals; | 
					
						
							|  |  |  |         int n = sVals.size() / nbMaxTicks; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 0; n*i < (int) sVals.size(); i++) { | 
					
						
							|  |  |  |             newSVals.push_back(sVals[sVals.size() -1 -n*i]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sVals = newSVals; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (nbAvailDb < (int) dbVals.size()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::vector<double> newDbVals; | 
					
						
							|  |  |  |         int n = dbVals.size() / nbAvailDb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 0; n*i < (int) dbVals.size(); i++) { | 
					
						
							|  |  |  |             newDbVals.push_back(dbVals[n*i]); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dbVals = newDbVals; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::adjustText(const QFontMetricsF& fontMetrics, Tick& tick) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     tick.textSize = fontMetrics.boundingRect(tick.text).width(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_orientation == Qt::Vertical) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         tick.textPos = tick.pos - fontMetrics.ascent() / 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double ScaleEngine::majorTickValue(int tick) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return m_firstMajorTickValue + (tick * m_majorTickValueDistance); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | double ScaleEngine::minorTickValue(int tick) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(m_numMinorTicks < 1) | 
					
						
							|  |  |  | 		return 0.0; | 
					
						
							| 
									
										
										
										
											2024-07-14 21:51:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 	return (m_majorTickValueDistance * tick) / m_numMinorTicks; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ScaleEngine::ScaleEngine() : | 
					
						
							|  |  |  | 	m_orientation(Qt::Horizontal), | 
					
						
							| 
									
										
										
										
											2017-05-05 10:40:45 +02:00
										 |  |  | 	m_charSize(8), | 
					
						
							| 
									
										
										
										
											2017-05-25 20:13:34 +02:00
										 |  |  |     m_size(1.0f), | 
					
						
							|  |  |  |     m_physicalUnit(Unit::None), | 
					
						
							|  |  |  |     m_rangeMin(-1.0), | 
					
						
							|  |  |  |     m_rangeMax(1.0), | 
					
						
							|  |  |  |     m_recalc(true), | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |     m_scale(1.0), | 
					
						
							| 
									
										
										
										
											2017-05-05 10:40:45 +02:00
										 |  |  | 	m_majorTickValueDistance(1.0), | 
					
						
							| 
									
										
										
										
											2017-05-25 20:13:34 +02:00
										 |  |  |     m_firstMajorTickValue(1.0), | 
					
						
							|  |  |  |     m_numMinorTicks(1), | 
					
						
							| 
									
										
										
										
											2017-07-22 04:23:10 +02:00
										 |  |  |     m_decimalPlaces(1), | 
					
						
							| 
									
										
										
										
											2018-07-08 18:59:09 +02:00
										 |  |  |     m_fixedDecimalPlaces(2), | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  |     m_makeOpposite(false), | 
					
						
							|  |  |  |     m_truncateMode(false), | 
					
						
							|  |  |  |     m_truncated(false), | 
					
						
							|  |  |  |     m_truncationValue(0.0) | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::setOrientation(Qt::Orientation orientation) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_orientation = orientation; | 
					
						
							|  |  |  | 	m_recalc = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::setFont(const QFont& font) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	m_font = font; | 
					
						
							|  |  |  | 	m_recalc = true; | 
					
						
							|  |  |  | 	calcCharSize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::setSize(float size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(size > 0.0f) { | 
					
						
							|  |  |  | 		m_size = size; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		m_size = 1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	m_recalc = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::setRange(Unit::Physical physicalUnit, float rangeMin, float rangeMax) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	double tmpRangeMin; | 
					
						
							|  |  |  | 	double tmpRangeMax; | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | 	if(rangeMin < rangeMax) { | 
					
						
							|  |  |  | 		tmpRangeMin = rangeMin; | 
					
						
							|  |  |  | 		tmpRangeMax = rangeMax; | 
					
						
							|  |  |  | 	} else if(rangeMin > rangeMax) { | 
					
						
							|  |  |  | 		tmpRangeMin = rangeMax; | 
					
						
							|  |  |  | 		tmpRangeMax = rangeMin; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		tmpRangeMin = rangeMin * 0.99; | 
					
						
							|  |  |  | 		tmpRangeMax = rangeMin * 1.01 + 0.01; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 	tmpRangeMin = rangeMin; | 
					
						
							|  |  |  | 	tmpRangeMax = rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 	if ((tmpRangeMin != m_rangeMin) || (tmpRangeMax != m_rangeMax) || (m_physicalUnit != physicalUnit)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | 		m_physicalUnit = physicalUnit; | 
					
						
							|  |  |  | 		m_rangeMin = tmpRangeMin; | 
					
						
							|  |  |  | 		m_rangeMax = tmpRangeMax; | 
					
						
							|  |  |  | 		m_recalc = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float ScaleEngine::getPosFromValue(double value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((value - m_rangeMin) / (m_rangeMax - m_rangeMin)) * (m_size - 1.0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float ScaleEngine::getValueFromPos(double pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ((pos * (m_rangeMax - m_rangeMin)) / (m_size - 1.0)) + m_rangeMin; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | float ScaleEngine::getPosFromValueTrunc(double value) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 	return ((value - rangeMin) / (rangeMax - rangeMin)) * (m_size - 1.0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float ScaleEngine::getValueFromPosTrunc(double pos) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 	return ((pos * (rangeMax - rangeMin)) / (m_size - 1.0)) + rangeMin; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | const ScaleEngine::TickList& ScaleEngine::getTickList() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	reCalc(); | 
					
						
							|  |  |  | 	return m_tickList; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString ScaleEngine::getRangeMinStr() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (m_unitStr.length() > 0) { | 
					
						
							|  |  |  | 		return QString("%1 %2").arg(formatTick(rangeMin / m_scale, m_decimalPlaces)).arg(m_unitStr); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         return QString("%1").arg(formatTick(rangeMin / m_scale, m_decimalPlaces)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString ScaleEngine::getRangeMaxStr() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  |     double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (m_unitStr.length() > 0) { | 
					
						
							|  |  |  | 		return QString("%1 %2").arg(formatTick(rangeMax / m_scale, m_decimalPlaces)).arg(m_unitStr); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         return QString("%1").arg(formatTick(rangeMax / m_scale, m_decimalPlaces)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-05-18 16:52:39 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | float ScaleEngine::getScaleWidth() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float max; | 
					
						
							|  |  |  | 	float len; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reCalc(); | 
					
						
							|  |  |  | 	max = 0.0f; | 
					
						
							|  |  |  | 	for(i = 0; i < m_tickList.count(); i++) { | 
					
						
							|  |  |  | 		len = m_tickList[i].textSize; | 
					
						
							|  |  |  | 		if(len > max) | 
					
						
							|  |  |  | 			max = len; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return max; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void ScaleEngine::setTruncateMode(bool mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qDebug("ScaleEngine::setTruncateMode: %s", (mode ? "on" : "off")); | 
					
						
							|  |  |  |     m_truncateMode = mode; | 
					
						
							|  |  |  |     m_recalc = true; | 
					
						
							|  |  |  |     reCalc(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-16 11:29:45 +02:00
										 |  |  | void ScaleEngine::updateTruncation() | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_truncated = false; | 
					
						
							|  |  |  |     m_truncationValue = 0.0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!m_truncateMode) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (order(m_rangeMax) != order(m_rangeMin)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     double width = m_rangeMax - m_rangeMin; | 
					
						
							|  |  |  |     int widthOrder = order(width); | 
					
						
							|  |  |  |     int maxOrder = order(m_rangeMax); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((widthOrder < 0) || (maxOrder < 0) || (widthOrder == maxOrder)) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = widthOrder+1; i <= maxOrder; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int irangeMin = floor(m_rangeMin / pow(10, i)); | 
					
						
							| 
									
										
										
										
											2022-10-16 12:57:54 +02:00
										 |  |  |         int irangeMax = floor(m_rangeMax / pow(10, i)); | 
					
						
							| 
									
										
										
										
											2022-10-16 04:48:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (irangeMin == irangeMax) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_truncated = true; | 
					
						
							|  |  |  |             m_truncationValue = irangeMin * pow(10, i); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     qDebug("ScaleEngine::updateTruncation: m_truncationValue: %f", m_truncationValue); | 
					
						
							|  |  |  | } |