KPlotting

kplotaxis.cpp
1 /* -*- C++ -*-
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2005 Andreas Nicolai <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kplotaxis.h"
9 
10 #include <math.h> //for log10(), pow(), modf()
11 
12 class KPlotAxis::Private
13 {
14 public:
15  Private(KPlotAxis *qq)
16  : q(qq)
17  , m_visible(true)
18  , m_showTickLabels(false)
19  , m_labelFmt('g')
20  , m_labelFieldWidth(0)
21  , m_labelPrec(-1)
22  {
23  }
24 
25  KPlotAxis *q;
26 
27  bool m_visible : 1; // Property "visible" defines if Axis is drawn or not.
28  bool m_showTickLabels : 1;
29  char m_labelFmt; // Number format for number labels, see QString::arg()
30  QString m_label; // The label of the axis.
31  int m_labelFieldWidth; // Field width for number labels, see QString::arg()
32  int m_labelPrec; // Number precision for number labels, see QString::arg()
33  QList<double> m_MajorTickMarks, m_MinorTickMarks;
34 };
35 
37  : d(new Private(this))
38 {
39  d->m_label = label;
40 }
41 
43 {
44  delete d;
45 }
46 
48 {
49  return d->m_visible;
50 }
51 
52 void KPlotAxis::setVisible(bool visible)
53 {
54  d->m_visible = visible;
55 }
56 
58 {
59  return d->m_showTickLabels;
60 }
61 
63 {
64  d->m_showTickLabels = b;
65 }
66 
67 void KPlotAxis::setLabel(const QString &label)
68 {
69  d->m_label = label;
70 }
71 
73 {
74  return d->m_label;
75 }
76 
77 void KPlotAxis::setTickLabelFormat(char format, int fieldWidth, int precision)
78 {
79  d->m_labelFieldWidth = fieldWidth;
80  d->m_labelFmt = format;
81  d->m_labelPrec = precision;
82 }
83 
85 {
86  return d->m_labelFieldWidth;
87 }
88 
90 {
91  return d->m_labelFmt;
92 }
93 
95 {
96  return d->m_labelPrec;
97 }
98 
99 void KPlotAxis::setTickMarks(double x0, double length)
100 {
101  d->m_MajorTickMarks.clear();
102  d->m_MinorTickMarks.clear();
103 
104  // s is the power-of-ten factor of length:
105  // length = t * s; s = 10^(pwr). e.g., length=350.0 then t=3.5, s = 100.0; pwr = 2.0
106  double pwr = 0.0;
107  modf(log10(length), &pwr);
108  double s = pow(10.0, pwr);
109  double t = length / s;
110 
111  double TickDistance = 0.0; // The distance between major tickmarks
112  int NumMajorTicks = 0; // will be between 3 and 5
113  int NumMinorTicks = 0; // The number of minor ticks between major ticks (will be 4 or 5)
114 
115  // adjust s and t such that t is between 3 and 5:
116  if (t < 3.0) {
117  t *= 10.0;
118  s /= 10.0;
119  // t is now between 3 and 30
120  }
121 
122  if (t < 6.0) { // accept current values
123  TickDistance = s;
124  NumMajorTicks = int(t);
125  NumMinorTicks = 5;
126  } else if (t < 10.0) { // adjust by a factor of 2
127  TickDistance = s * 2.0;
128  NumMajorTicks = int(t / 2.0);
129  NumMinorTicks = 4;
130  } else if (t < 20.0) { // adjust by a factor of 4
131  TickDistance = s * 4.0;
132  NumMajorTicks = int(t / 4.0);
133  NumMinorTicks = 4;
134  } else { // adjust by a factor of 5
135  TickDistance = s * 5.0;
136  NumMajorTicks = int(t / 5.0);
137  NumMinorTicks = 5;
138  }
139 
140  // We have determined the number of tickmarks and their separation
141  // Now we determine their positions in the Data space.
142 
143  // Tick0 is the position of a "virtual" tickmark; the first major tickmark
144  // position beyond the "minimum" edge of the data range.
145  double Tick0 = x0 - fmod(x0, TickDistance);
146  if (x0 < 0.0) {
147  Tick0 -= TickDistance;
148  NumMajorTicks++;
149  }
150 
151  for (int i = 0; i < NumMajorTicks + 2; i++) {
152  double xmaj = Tick0 + i * TickDistance;
153  if (xmaj >= x0 && xmaj <= x0 + length) {
154  d->m_MajorTickMarks.append(xmaj);
155  }
156 
157  for (int j = 1; j < NumMinorTicks; j++) {
158  double xmin = xmaj + TickDistance * j / NumMinorTicks;
159  if (xmin >= x0 && xmin <= x0 + length) {
160  d->m_MinorTickMarks.append(xmin);
161  }
162  }
163  }
164 }
165 
166 QString KPlotAxis::tickLabel(double val) const
167 {
168  if (d->m_labelFmt == 't') {
169  while (val < 0.0) {
170  val += 24.0;
171  }
172  while (val >= 24.0) {
173  val -= 24.0;
174  }
175 
176  int h = int(val);
177  int m = int(60. * (val - h));
178  return QStringLiteral("%1:%2").arg(h, 2, 10, QLatin1Char('0')).arg(m, 2, 10, QLatin1Char('0'));
179  }
180 
181  return QStringLiteral("%1").arg(val, d->m_labelFieldWidth, d->m_labelFmt, d->m_labelPrec);
182 }
183 
185 {
186  return d->m_MajorTickMarks;
187 }
188 
190 {
191  return d->m_MinorTickMarks;
192 }
void setTickLabelsShown(bool b)
Determine whether tick labels will be drawn for this axis.
Definition: kplotaxis.cpp:62
bool areTickLabelsShown() const
Definition: kplotaxis.cpp:57
QList< double > majorTickMarks() const
Definition: kplotaxis.cpp:184
bool isVisible() const
Definition: kplotaxis.cpp:47
Axis for KPlotWidget.
Definition: kplotaxis.h:24
char tickLabelFormat() const
Definition: kplotaxis.cpp:89
void setLabel(const QString &label)
Sets the axis label.
Definition: kplotaxis.cpp:67
QString label() const
Definition: kplotaxis.cpp:72
void setVisible(bool visible)
Sets the "visible" property of the axis.
Definition: kplotaxis.cpp:52
int tickLabelWidth() const
Definition: kplotaxis.cpp:84
~KPlotAxis()
Destructor.
Definition: kplotaxis.cpp:42
void setTickLabelFormat(char format='g', int fieldWidth=0, int precision=-1)
Set the display format for converting the double value of the tick's position to the QString for the ...
Definition: kplotaxis.cpp:77
int tickLabelPrecision() const
Definition: kplotaxis.cpp:94
QList< double > minorTickMarks() const
Definition: kplotaxis.cpp:189
void setTickMarks(double x0, double length)
Determine the positions of major and minor tickmarks for this axis.
Definition: kplotaxis.cpp:99
KPlotAxis(const QString &label=QString())
Constructor, constructs an axis with the label label.
Definition: kplotaxis.cpp:36
QString tickLabel(double value) const
Definition: kplotaxis.cpp:166
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Dec 5 2023 03:52:27 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.