2017-04-27 20:26:36 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2016-04-04 22:02:03 -07:00
|
|
|
#include "profile-widget/divecartesianaxis.h"
|
|
|
|
#include "profile-widget/divetextitem.h"
|
2018-06-03 22:15:19 +02:00
|
|
|
#include "core/qthelper.h"
|
2018-05-11 08:25:41 -07:00
|
|
|
#include "core/subsurface-string.h"
|
2016-04-04 22:02:03 -07:00
|
|
|
#include "qt-models/diveplotdatamodel.h"
|
|
|
|
#include "profile-widget/animationfunctions.h"
|
|
|
|
#include "profile-widget/divelineitem.h"
|
2021-06-28 20:29:46 +02:00
|
|
|
#include "profile-widget/profilescene.h"
|
2014-01-14 16:20:15 -02:00
|
|
|
|
2021-08-28 14:25:04 +02:00
|
|
|
static const double labelSpaceHorizontal = 2.0; // space between label and ticks
|
|
|
|
static const double labelSpaceVertical = 2.0; // space between label and ticks
|
2021-08-11 10:57:42 +02:00
|
|
|
|
2021-09-11 21:57:49 +02:00
|
|
|
void DiveCartesianAxis::setBounds(double minimum, double maximum)
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
2021-09-11 21:57:49 +02:00
|
|
|
changed = !IS_FP_SAME(max, maximum) || !IS_FP_SAME(min, minimum);
|
2021-09-26 19:10:39 +02:00
|
|
|
dataMin = min = minimum;
|
|
|
|
dataMax = max = maximum;
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
2021-09-20 21:13:19 +02:00
|
|
|
DiveCartesianAxis::DiveCartesianAxis(Position position, int integralDigits, int fractionalDigits, color_index_t gridColor, double dpr,
|
2021-09-11 22:14:45 +02:00
|
|
|
double labelScale, bool printMode, bool isGrayscale, ProfileScene &scene) :
|
2021-08-03 15:39:25 +02:00
|
|
|
printMode(printMode),
|
2021-08-28 20:12:36 +02:00
|
|
|
position(position),
|
2021-09-22 20:56:13 +02:00
|
|
|
fractionalDigits(fractionalDigits),
|
2021-08-28 20:12:36 +02:00
|
|
|
gridColor(gridColor),
|
2021-06-28 20:29:46 +02:00
|
|
|
scene(scene),
|
2014-02-09 18:37:40 +01:00
|
|
|
orientation(LeftToRight),
|
|
|
|
min(0),
|
|
|
|
max(0),
|
2014-02-15 21:55:31 -02:00
|
|
|
textVisibility(true),
|
2014-02-17 14:39:03 -08:00
|
|
|
lineVisibility(true),
|
2021-09-11 22:14:45 +02:00
|
|
|
labelScale(labelScale),
|
2021-06-03 17:19:38 +02:00
|
|
|
changed(true),
|
2021-09-22 20:56:13 +02:00
|
|
|
dpr(dpr),
|
|
|
|
transform({1.0, 0.0})
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
2021-09-01 21:18:38 +02:00
|
|
|
QPen pen;
|
|
|
|
pen.setColor(getColor(TIME_GRID, isGrayscale));
|
|
|
|
/* cosmetic width() == 0 for lines in printMode
|
|
|
|
* having setCosmetic(true) and width() > 0 does not work when
|
|
|
|
* printing on OSX and Linux */
|
|
|
|
pen.setWidth(DiveCartesianAxis::printMode ? 0 : 2);
|
|
|
|
pen.setCosmetic(true);
|
|
|
|
setPen(pen);
|
|
|
|
|
|
|
|
pen.setBrush(getColor(gridColor, isGrayscale));
|
|
|
|
gridPen = pen;
|
2021-09-20 21:13:19 +02:00
|
|
|
|
|
|
|
/* Create the longest expected label, e.g. 999.99. */
|
|
|
|
QString label;
|
|
|
|
label.reserve(integralDigits + fractionalDigits + 1);
|
|
|
|
for (int i = 0; i < integralDigits; ++i)
|
|
|
|
label.append('9');
|
|
|
|
if (fractionalDigits > 0) {
|
|
|
|
label.append('.');
|
|
|
|
for (int i = 0; i < fractionalDigits; ++i)
|
|
|
|
label.append('9');
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use the label to estimate size of the labels.
|
|
|
|
* Round up, because non-integers tend to give abysmal rendering.
|
|
|
|
*/
|
|
|
|
QFont fnt = DiveTextItem::getFont(dpr, labelScale);
|
|
|
|
double outlineSpace = DiveTextItem::outlineSpace(dpr);
|
|
|
|
QFontMetrics fm(fnt);
|
|
|
|
labelWidth = ceil(fm.size(Qt::TextSingleLine, label).width() + outlineSpace);
|
|
|
|
labelHeight = ceil(fm.height() + outlineSpace);
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
DiveCartesianAxis::~DiveCartesianAxis()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-01-16 19:28:33 -02:00
|
|
|
void DiveCartesianAxis::setOrientation(Orientation o)
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
|
|
|
orientation = o;
|
2014-05-26 18:01:38 -03:00
|
|
|
changed = true;
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
2021-09-22 20:56:13 +02:00
|
|
|
void DiveCartesianAxis::setTransform(double a, double b)
|
|
|
|
{
|
|
|
|
transform.a = a;
|
|
|
|
transform.b = b;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
QColor DiveCartesianAxis::colorForValue(double) const
|
2014-01-19 20:14:48 -02:00
|
|
|
{
|
|
|
|
return QColor(Qt::black);
|
|
|
|
}
|
|
|
|
|
2014-02-12 14:24:19 -02:00
|
|
|
void DiveCartesianAxis::setTextVisible(bool arg1)
|
|
|
|
{
|
2014-02-27 20:09:57 -08:00
|
|
|
if (textVisibility == arg1) {
|
2014-02-12 14:24:19 -02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
textVisibility = arg1;
|
2014-05-22 11:40:22 -07:00
|
|
|
Q_FOREACH (DiveTextItem *item, labels) {
|
2014-02-12 14:24:19 -02:00
|
|
|
item->setVisible(textVisibility);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-15 22:54:41 -02:00
|
|
|
void DiveCartesianAxis::setLinesVisible(bool arg1)
|
|
|
|
{
|
2014-02-27 20:09:57 -08:00
|
|
|
if (lineVisibility == arg1) {
|
2014-02-15 22:54:41 -02:00
|
|
|
return;
|
|
|
|
}
|
2014-02-27 20:09:57 -08:00
|
|
|
lineVisibility = arg1;
|
2014-05-22 11:40:22 -07:00
|
|
|
Q_FOREACH (DiveLineItem *item, lines) {
|
2014-02-27 20:09:57 -08:00
|
|
|
item->setVisible(lineVisibility);
|
2014-02-15 22:54:41 -02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-27 20:09:57 -08:00
|
|
|
template <typename T>
|
2019-07-10 22:40:06 +02:00
|
|
|
void emptyList(QList<T *> &list, int steps, int speed)
|
2014-02-27 20:09:57 -08:00
|
|
|
{
|
2018-05-19 07:37:58 +02:00
|
|
|
while (list.size() > steps) {
|
|
|
|
T *removedItem = list.takeLast();
|
2019-07-10 22:40:06 +02:00
|
|
|
Animations::animDelete(removedItem, speed);
|
2014-02-15 21:55:31 -02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 10:57:42 +02:00
|
|
|
double DiveCartesianAxis::width() const
|
|
|
|
{
|
2021-09-20 21:13:19 +02:00
|
|
|
return labelWidth + labelSpaceHorizontal * dpr;
|
2021-08-11 10:57:42 +02:00
|
|
|
}
|
|
|
|
|
2021-08-28 14:25:04 +02:00
|
|
|
double DiveCartesianAxis::height() const
|
|
|
|
{
|
2021-09-20 21:13:19 +02:00
|
|
|
return labelHeight + labelSpaceVertical * dpr;
|
2021-08-28 14:25:04 +02:00
|
|
|
}
|
|
|
|
|
2021-08-28 20:15:57 +02:00
|
|
|
void DiveCartesianAxis::updateTicks(int animSpeed)
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
2021-06-28 20:29:46 +02:00
|
|
|
if (!changed && !printMode)
|
2014-01-25 07:25:03 -08:00
|
|
|
return;
|
2021-09-26 19:10:39 +02:00
|
|
|
|
|
|
|
if (dataMax - dataMin < 1e-5)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Guess the number of tick marks.
|
2014-01-14 16:20:15 -02:00
|
|
|
QLineF m = line();
|
2021-09-26 19:10:39 +02:00
|
|
|
double spaceNeeded = position == Position::Bottom ? labelWidth * 3.0 / 2.0
|
|
|
|
: labelHeight * 2.0;
|
|
|
|
double size = position == Position::Bottom ? fabs(m.x2() - m.x1())
|
|
|
|
: fabs(m.y2() - m.y1());
|
|
|
|
int numTicks = lrint(size / spaceNeeded);
|
|
|
|
|
|
|
|
numTicks = std::clamp(numTicks, 2, 50);
|
|
|
|
double interval = (dataMax - dataMin) / numTicks;
|
|
|
|
|
|
|
|
// Round the interval to a sensible size in display units
|
|
|
|
double intervalDisplay = interval * transform.a;
|
|
|
|
intervalDisplay = ceil(intervalDisplay); // Currently, round to full integers, might want to improve.
|
|
|
|
|
|
|
|
// Choose full multiples of the interval as minumum and maximum values
|
|
|
|
double minDisplay = transform.to(dataMin);
|
|
|
|
double maxDisplay = transform.to(dataMax);
|
|
|
|
double firstDisplay = floor(minDisplay / intervalDisplay * (1.0 + 1e-5)) * intervalDisplay;
|
|
|
|
double lastDisplay = ceil(maxDisplay / intervalDisplay * (1.0 - 1e-5)) * intervalDisplay;
|
|
|
|
numTicks = lrint((lastDisplay - firstDisplay) / intervalDisplay) + 1;
|
|
|
|
numTicks = std::max(numTicks, 0);
|
|
|
|
|
|
|
|
min = transform.from(firstDisplay);
|
|
|
|
max = transform.from(lastDisplay);
|
|
|
|
|
2014-02-15 22:15:45 -02:00
|
|
|
double currValueText = min;
|
|
|
|
double currValueLine = min;
|
2014-01-14 16:20:15 -02:00
|
|
|
|
2021-09-26 19:10:39 +02:00
|
|
|
emptyList(labels, numTicks, animSpeed);
|
|
|
|
emptyList(lines, numTicks, animSpeed);
|
|
|
|
if (numTicks == 0)
|
2014-01-27 15:14:42 -02:00
|
|
|
return;
|
2014-01-27 17:09:08 -02:00
|
|
|
|
2021-09-26 19:10:39 +02:00
|
|
|
interval = numTicks > 1 ? (max - min) / (numTicks - 1) : 0;
|
|
|
|
double stepSize = numTicks > 1 ? size / (numTicks - 1) : 0;
|
2014-02-15 21:55:31 -02:00
|
|
|
|
2021-08-28 23:36:09 +02:00
|
|
|
// Move the remaining grid lines / labels to their correct positions
|
2018-05-19 07:37:58 +02:00
|
|
|
// regarding the possible new values for the axis
|
2021-09-26 19:10:39 +02:00
|
|
|
double begin;
|
2014-01-16 19:28:33 -02:00
|
|
|
if (orientation == TopToBottom) {
|
|
|
|
begin = m.y1();
|
|
|
|
} else if (orientation == BottomToTop) {
|
|
|
|
begin = m.y2();
|
2014-02-27 20:09:57 -08:00
|
|
|
} else if (orientation == LeftToRight) {
|
2014-01-16 19:28:33 -02:00
|
|
|
begin = m.x1();
|
2014-06-11 09:37:12 -07:00
|
|
|
} else /* if (orientation == RightToLeft) */ {
|
2014-01-16 19:28:33 -02:00
|
|
|
begin = m.x2();
|
|
|
|
}
|
|
|
|
|
2014-02-15 22:15:45 -02:00
|
|
|
for (int i = 0, count = labels.size(); i < count; i++, currValueText += interval) {
|
2021-08-28 23:36:09 +02:00
|
|
|
double childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
|
2014-05-22 11:40:22 -07:00
|
|
|
begin + i * stepSize :
|
|
|
|
begin - i * stepSize;
|
2014-01-27 17:09:08 -02:00
|
|
|
|
2021-08-13 09:56:46 +02:00
|
|
|
labels[i]->set(textForValue(currValueText), colorForValue(currValueText));
|
2021-08-28 23:36:09 +02:00
|
|
|
switch (position) {
|
|
|
|
default:
|
|
|
|
case Position::Bottom:
|
|
|
|
Animations::moveTo(labels[i], animSpeed, childPos, rect.bottom() + labelSpaceVertical * dpr);
|
|
|
|
break;
|
|
|
|
case Position::Left:
|
|
|
|
Animations::moveTo(labels[i], animSpeed, rect.left() - labelSpaceHorizontal * dpr, childPos);
|
|
|
|
break;
|
|
|
|
case Position::Right:
|
|
|
|
Animations::moveTo(labels[i], animSpeed, rect.right() + labelSpaceHorizontal * dpr, childPos);
|
|
|
|
break;
|
2014-01-14 16:24:33 -02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-15 22:15:45 -02:00
|
|
|
for (int i = 0, count = lines.size(); i < count; i++, currValueLine += interval) {
|
2021-08-28 23:36:09 +02:00
|
|
|
double childPos = (orientation == TopToBottom || orientation == LeftToRight) ?
|
2014-05-22 11:40:22 -07:00
|
|
|
begin + i * stepSize :
|
|
|
|
begin - i * stepSize;
|
2014-02-15 22:15:45 -02:00
|
|
|
|
2021-08-28 23:36:09 +02:00
|
|
|
if (position == Position::Bottom) {
|
|
|
|
// Fix size in case the scene changed
|
|
|
|
QLineF old = lines[i]->line();
|
|
|
|
lines[i]->setLine(old.x1(), old.y1(), old.x1(), old.y1() + rect.height());
|
|
|
|
Animations::moveTo(lines[i], animSpeed, childPos, rect.top());
|
2014-02-15 22:15:45 -02:00
|
|
|
} else {
|
2021-08-28 23:36:09 +02:00
|
|
|
// Fix size in case the scene changed
|
|
|
|
QLineF old = lines[i]->line();
|
|
|
|
lines[i]->setLine(old.x1(), old.y1(), old.x1() + rect.width(), old.y1());
|
|
|
|
Animations::moveTo(lines[i], animSpeed, rect.left(), childPos);
|
2014-02-15 22:15:45 -02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-28 23:36:09 +02:00
|
|
|
// Add the rest of the needed labels.
|
2021-09-26 19:10:39 +02:00
|
|
|
for (int i = labels.size(); i < numTicks; i++, currValueText += interval) {
|
2021-08-28 23:36:09 +02:00
|
|
|
double childPos;
|
2014-01-16 19:28:33 -02:00
|
|
|
if (orientation == TopToBottom || orientation == LeftToRight) {
|
2014-02-27 20:09:57 -08:00
|
|
|
childPos = begin + i * stepSize;
|
2014-01-16 19:28:33 -02:00
|
|
|
} else {
|
|
|
|
childPos = begin - i * stepSize;
|
|
|
|
}
|
2021-08-28 23:36:09 +02:00
|
|
|
int alignFlags = position == Position::Bottom ? Qt::AlignTop | Qt::AlignHCenter :
|
|
|
|
position == Position::Left ? Qt::AlignVCenter | Qt::AlignLeft:
|
|
|
|
Qt::AlignVCenter | Qt::AlignRight;
|
2021-08-12 22:57:57 +02:00
|
|
|
DiveTextItem *label = new DiveTextItem(dpr, labelScale, alignFlags, this);
|
2021-08-13 09:56:46 +02:00
|
|
|
label->set(textForValue(currValueText), colorForValue(currValueText));
|
2014-02-15 22:49:30 -02:00
|
|
|
label->setZValue(1);
|
2014-02-07 18:08:29 -02:00
|
|
|
labels.push_back(label);
|
2021-08-28 23:36:09 +02:00
|
|
|
switch (position) {
|
|
|
|
default:
|
|
|
|
case Position::Bottom:
|
|
|
|
label->setPos(scene.sceneRect().width() + 10, rect.bottom() + labelSpaceVertical * dpr); // position it outside of the scene;
|
|
|
|
Animations::moveTo(labels[i], animSpeed, childPos, rect.bottom() + labelSpaceVertical * dpr);
|
|
|
|
break;
|
|
|
|
case Position::Left:
|
|
|
|
label->setPos(rect.left() - labelSpaceHorizontal * dpr, scene.sceneRect().height() + 10);
|
|
|
|
Animations::moveTo(labels[i], animSpeed, rect.left() - labelSpaceHorizontal * dpr, childPos);
|
|
|
|
break;
|
|
|
|
case Position::Right:
|
|
|
|
label->setPos(rect.right() + labelSpaceHorizontal * dpr, scene.sceneRect().height() + 10);
|
|
|
|
Animations::moveTo(labels[i], animSpeed, rect.right() + labelSpaceHorizontal * dpr, childPos);
|
|
|
|
break;
|
2014-01-14 16:28:07 -02:00
|
|
|
}
|
|
|
|
}
|
2014-02-12 14:24:19 -02:00
|
|
|
|
2021-08-28 23:36:09 +02:00
|
|
|
// Add the rest of the needed grid lines.
|
2021-09-26 19:10:39 +02:00
|
|
|
for (int i = lines.size(); i < numTicks; i++, currValueText += interval) {
|
2021-08-28 23:36:09 +02:00
|
|
|
double childPos;
|
2014-02-15 22:43:27 -02:00
|
|
|
if (orientation == TopToBottom || orientation == LeftToRight) {
|
2014-02-27 20:09:57 -08:00
|
|
|
childPos = begin + i * stepSize;
|
2014-02-15 22:43:27 -02:00
|
|
|
} else {
|
|
|
|
childPos = begin - i * stepSize;
|
|
|
|
}
|
|
|
|
DiveLineItem *line = new DiveLineItem(this);
|
2021-09-01 21:18:38 +02:00
|
|
|
line->setPen(gridPen);
|
2014-02-15 22:49:30 -02:00
|
|
|
line->setZValue(0);
|
2014-02-15 22:43:27 -02:00
|
|
|
lines.push_back(line);
|
2021-08-28 23:36:09 +02:00
|
|
|
if (position == Position::Bottom) {
|
|
|
|
line->setLine(0.0, 0.0, 0.0, rect.height());
|
|
|
|
line->setPos(scene.sceneRect().width() + 10, rect.top()); // position it outside of the scene);
|
|
|
|
Animations::moveTo(line, animSpeed, childPos, rect.top());
|
2014-02-15 22:43:27 -02:00
|
|
|
} else {
|
2021-08-28 23:36:09 +02:00
|
|
|
line->setLine(0.0, 0.0, rect.width(), 0.0);
|
|
|
|
line->setPos(rect.left(), scene.sceneRect().height() + 10);
|
|
|
|
Animations::moveTo(line, animSpeed, rect.left(), childPos);
|
2014-02-15 22:43:27 -02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 11:40:22 -07:00
|
|
|
Q_FOREACH (DiveTextItem *item, labels)
|
2014-03-03 13:25:55 -08:00
|
|
|
item->setVisible(textVisibility);
|
2014-05-22 11:40:22 -07:00
|
|
|
Q_FOREACH (DiveLineItem *item, lines)
|
2014-03-03 13:25:55 -08:00
|
|
|
item->setVisible(lineVisibility);
|
2014-05-26 18:01:38 -03:00
|
|
|
changed = false;
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
2014-07-29 18:48:17 -03:00
|
|
|
void DiveCartesianAxis::setLine(const QLineF &line)
|
|
|
|
{
|
|
|
|
QGraphicsLineItem::setLine(line);
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
2021-08-28 23:36:09 +02:00
|
|
|
void DiveCartesianAxis::animateChangeLine(const QRectF &rectIn, int animSpeed)
|
|
|
|
{
|
|
|
|
rect = rectIn;
|
|
|
|
switch (position) {
|
|
|
|
case Position::Left:
|
|
|
|
setLine(QLineF(rect.topLeft(), rect.bottomLeft()));
|
|
|
|
break;
|
|
|
|
case Position::Right:
|
|
|
|
setLine(QLineF(rect.topRight(), rect.bottomRight()));
|
|
|
|
break;
|
|
|
|
case Position::Bottom:
|
|
|
|
default:
|
|
|
|
setLine(QLineF(rect.bottomLeft(), rect.bottomRight()));
|
|
|
|
break;
|
|
|
|
}
|
2021-08-03 10:32:08 +02:00
|
|
|
updateTicks(animSpeed);
|
2014-01-22 17:10:18 -02:00
|
|
|
sizeChanged();
|
|
|
|
}
|
|
|
|
|
2021-09-22 20:56:13 +02:00
|
|
|
double DiveCartesianAxis::Transform::to(double x) const
|
|
|
|
{
|
|
|
|
return a*x + b;
|
|
|
|
}
|
|
|
|
|
|
|
|
double DiveCartesianAxis::Transform::from(double y) const
|
|
|
|
{
|
|
|
|
return (y - b) / a;
|
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
QString DiveCartesianAxis::textForValue(double value) const
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
2021-09-22 20:56:13 +02:00
|
|
|
return QStringLiteral("%L1").arg(transform.to(value), 0, 'f', fractionalDigits);
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
2014-02-27 20:09:57 -08:00
|
|
|
qreal DiveCartesianAxis::valueAt(const QPointF &p) const
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
2019-08-08 11:30:41 +02:00
|
|
|
double fraction;
|
2014-01-14 16:20:15 -02:00
|
|
|
QLineF m = line();
|
2014-02-11 12:05:33 -08:00
|
|
|
QPointF relativePosition = p;
|
|
|
|
relativePosition -= pos(); // normalize p based on the axis' offset on screen
|
|
|
|
|
2019-08-08 11:30:41 +02:00
|
|
|
if (orientation == LeftToRight || orientation == RightToLeft)
|
|
|
|
fraction = (relativePosition.x() - m.x1()) / (m.x2() - m.x1());
|
|
|
|
else
|
|
|
|
fraction = (relativePosition.y() - m.y1()) / (m.y2() - m.y1());
|
|
|
|
|
|
|
|
if (orientation == RightToLeft || orientation == BottomToTop)
|
|
|
|
fraction = 1 - fraction;
|
|
|
|
return fraction * (max - min) + min;
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
qreal DiveCartesianAxis::posAtValue(qreal value) const
|
2014-01-14 16:20:15 -02:00
|
|
|
{
|
|
|
|
QLineF m = line();
|
|
|
|
QPointF p = pos();
|
|
|
|
|
|
|
|
double size = max - min;
|
2014-01-17 06:30:47 +07:00
|
|
|
// unused for now:
|
|
|
|
// double distanceFromOrigin = value - min;
|
2014-02-27 20:09:57 -08:00
|
|
|
double percent = IS_FP_SAME(min, max) ? 0.0 : (value - min) / size;
|
2014-01-21 21:43:07 +01:00
|
|
|
|
2014-01-16 19:28:33 -02:00
|
|
|
|
2014-02-27 20:09:57 -08:00
|
|
|
double realSize = orientation == LeftToRight || orientation == RightToLeft ?
|
2014-05-22 11:40:22 -07:00
|
|
|
m.x2() - m.x1() :
|
|
|
|
m.y2() - m.y1();
|
2014-01-16 19:28:33 -02:00
|
|
|
|
|
|
|
// Inverted axis, just invert the percentage.
|
2014-01-17 06:30:47 +07:00
|
|
|
if (orientation == RightToLeft || orientation == BottomToTop)
|
2014-01-16 19:28:33 -02:00
|
|
|
percent = 1 - percent;
|
|
|
|
|
2014-01-14 16:20:15 -02:00
|
|
|
double retValue = realSize * percent;
|
2014-01-16 19:28:33 -02:00
|
|
|
double adjusted =
|
2014-05-22 11:40:22 -07:00
|
|
|
orientation == LeftToRight ? retValue + m.x1() + p.x() :
|
2014-07-29 16:34:57 -03:00
|
|
|
orientation == RightToLeft ? retValue + m.x1() + p.x() :
|
|
|
|
orientation == TopToBottom ? retValue + m.y1() + p.y() :
|
|
|
|
/* entation == BottomToTop */ retValue + m.y1() + p.y();
|
2014-01-16 18:39:13 -02:00
|
|
|
return adjusted;
|
2014-01-14 16:20:15 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
double DiveCartesianAxis::maximum() const
|
|
|
|
{
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
|
|
|
double DiveCartesianAxis::minimum() const
|
|
|
|
{
|
|
|
|
return min;
|
|
|
|
}
|
|
|
|
|
2021-08-29 22:13:26 +02:00
|
|
|
std::pair<double, double> DiveCartesianAxis::screenMinMax() const
|
|
|
|
{
|
|
|
|
return position == Position::Bottom ? std::make_pair(rect.left(), rect.right())
|
|
|
|
: std::make_pair(rect.top(), rect.bottom());
|
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
QColor DepthAxis::colorForValue(double) const
|
2014-01-19 20:14:48 -02:00
|
|
|
{
|
|
|
|
return QColor(Qt::red);
|
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
QColor TimeAxis::colorForValue(double) const
|
2014-01-19 20:14:48 -02:00
|
|
|
{
|
|
|
|
return QColor(Qt::blue);
|
|
|
|
}
|
|
|
|
|
2020-12-20 13:01:21 +01:00
|
|
|
QString TimeAxis::textForValue(double value) const
|
2014-01-15 11:08:31 -02:00
|
|
|
{
|
2017-03-23 08:13:49 +07:00
|
|
|
int nr = lrint(value) / 60;
|
2014-02-27 20:09:57 -08:00
|
|
|
if (maximum() < 600)
|
|
|
|
return QString("%1:%2").arg(nr).arg((int)value % 60, 2, 10, QChar('0'));
|
|
|
|
return QString::number(nr);
|
2014-01-16 11:50:56 +07:00
|
|
|
}
|