14#include "KDChartPainterSaver_p.h"
19#include <KDABLibFakes>
27 Q_ASSERT_X(rawDataDimensions.
count() == 2,
"CartesianGrid::calculateGrid",
28 "Error: calculateGrid() expects a list with exactly two entries.");
31 Q_ASSERT_X(plane,
"LeveyJenningsGrid::calculateGrid",
32 "Error: PaintContext::calculatePlane() called, but no cartesian plane set.");
38 const QPointF translatedBottomLeft(plane->translateBack(plane->geometry().bottomLeft()));
39 const QPointF translatedTopRight(plane->translateBack(plane->geometry().topRight()));
41 if (l.first().isCalculated
42 && plane->autoAdjustGridToZoom()
44 && plane->zoomFactorX() > 1.0) {
45 l.first().start = translatedBottomLeft.x();
46 l.first().end = translatedTopRight.x();
54 if (plane->autoAdjustGridToZoom()
56 && plane->zoomFactorY() > 1.0) {
57 l.last().start = translatedBottomLeft.y();
58 l.last().end = translatedTopRight.y();
63 l.first().start = dimX.
start;
64 l.first().end = dimX.
end;
67 l.last().start = minMaxY.
start;
68 l.last().end = minMaxY.
end;
75 l.last().subStepWidth = dimY.
stepWidth / 2;
88#define trunc(x) (( int )(x))
94 bool adjustLower,
bool adjustUpper)
const
97 if (dim.isCalculated && dim.start != dim.end) {
99 if (dim.stepWidth == 0.0) {
101 switch (dim.sequence) {
103 granularities << 1.0 << 2.0;
106 granularities << 1.0 << 5.0;
109 granularities << 2.5 << 5.0;
112 granularities << 1.25 << 2.5;
115 granularities << 1.0 << 1.25 << 2.0 << 2.5 << 5.0;
120 dim.start, dim.end, granularities, orientation,
121 dim.stepWidth, dim.subStepWidth,
122 adjustLower, adjustUpper);
127 dim.stepWidth = dim.stepWidth ? dim.stepWidth : 1.0;
134 int minSteps,
int maxSteps,
136 qreal &steps, qreal &stepWidth,
137 bool adjustLower,
bool adjustUpper)
141 qreal distance = 0.0;
144 const int lastIdx = list.
count() - 1;
145 for (
int i = 0; i <= lastIdx; ++i) {
146 const qreal testStepWidth = list.
at(lastIdx - i) *
fastPow10(power);
148 qreal start = qMin(start_, end_);
149 qreal end = qMax(start_, end_);
154 const qreal testDistance = qAbs(end - start);
155 const qreal testSteps = testDistance / testStepWidth;
158 if ((minSteps <= testSteps) && (testSteps <= maxSteps)
159 && ((steps == 0.0) || (testDistance <= distance))) {
161 stepWidth = testStepWidth;
162 distance = testDistance;
168void LeveyJenningsGrid::calculateStepWidth(
169 qreal start_, qreal end_,
172 qreal &stepWidth, qreal &subStepWidth,
173 bool adjustLower,
bool adjustUpper)
const
175 Q_UNUSED(orientation);
177 Q_ASSERT_X(granularities.
count(),
"CartesianGrid::calculateStepWidth",
178 "Error: The list of GranularitySequence values is empty.");
180 std::sort(list.begin(), list.end());
182 const qreal start = qMin(start_, end_);
183 const qreal end = qMax(start_, end_);
184 const qreal distance = end - start;
188 const int minSteps = 2;
189 const int maxSteps = 12;
193 while (list.last() *
fastPow10(power) < distance) {
198 const int count = list.count();
200 for (
int i = 0; i < count; ++i)
201 testList << list.
at(i) * 0.1;
208 adjustLower, adjustUpper);
210 }
while (steps == 0.0);
217 if (subStepWidth == 0.0) {
218 if (stepWidth == list.first() *
fastPow10(power)) {
219 subStepWidth = list.last() *
fastPow10(power - 1);
221 }
else if (stepWidth == list.first() *
fastPow10(power - 1)) {
222 subStepWidth = list.last() *
fastPow10(power - 2);
225 qreal smallerStepWidth = list.first();
226 for (
int i = 1; i < list.count(); ++i) {
227 if (stepWidth == list.at(i) *
fastPow10(power)) {
228 subStepWidth = smallerStepWidth *
fastPow10(power);
231 if (stepWidth == list.at(i) *
fastPow10(power - 1)) {
232 subStepWidth = smallerStepWidth *
fastPow10(power - 1);
235 smallerStepWidth = list.at(i);
247 PainterSaver p(context->
painter());
248 auto *plane = qobject_cast<LeveyJenningsCoordinatePlane *>(
250 Q_ASSERT_X(plane,
"LeveyJenningsGrid::drawGrid",
251 "Bad function call: PaintContext::coodinatePlane() NOT a Levey Jennings plane.");
253 auto *diag = qobject_cast<LeveyJenningsDiagram *>(plane->diagram());
265 "Error: updateData did not return exactly two dimensions.");
275 if (dimX.
start == 0.0 && dimX.
end == 0.0)
276 dimX.
end += plane->geometry().width();
280 const float meanValue = diag->expectedMeanValue();
281 const float standardDeviation = diag->expectedStandardDeviation();
284 const float calcMeanValue = diag->calculatedMeanValue();
285 const float calcStandardDeviation = diag->calculatedStandardDeviation();
288 QPointF topLeft = plane->translate(
QPointF(dimX.
start, meanValue - 2 * standardDeviation));
289 QPointF bottomRight = plane->translate(
QPointF(dimX.
end, meanValue + 2 * standardDeviation));
294 topLeft = plane->translate(
QPointF(dimX.
start, meanValue + 2 * standardDeviation));
295 bottomRight = plane->translate(
QPointF(dimX.
end, meanValue + 3 * standardDeviation));
299 topLeft = plane->translate(
QPointF(dimX.
start, meanValue - 2 * standardDeviation));
300 bottomRight = plane->translate(
QPointF(dimX.
end, meanValue - 3 * standardDeviation));
305 topLeft = plane->translate(
QPointF(dimX.
start, meanValue + 3 * standardDeviation));
306 bottomRight = plane->translate(
QPointF(dimX.
end, meanValue + 4 * standardDeviation));
310 topLeft = plane->translate(
QPointF(dimX.
start, meanValue - 3 * standardDeviation));
311 bottomRight = plane->translate(
QPointF(dimX.
end, meanValue - 4 * standardDeviation));
319 plane->translate(
QPointF(dimX.
end, meanValue)));
321 plane->translate(
QPointF(dimX.
end, meanValue + 2 * standardDeviation)));
323 plane->translate(
QPointF(dimX.
end, meanValue + 3 * standardDeviation)));
325 plane->translate(
QPointF(dimX.
end, meanValue + 4 * standardDeviation)));
327 plane->translate(
QPointF(dimX.
end, meanValue - 2 * standardDeviation)));
329 plane->translate(
QPointF(dimX.
end, meanValue - 3 * standardDeviation)));
331 plane->translate(
QPointF(dimX.
end, meanValue - 4 * standardDeviation)));
338 plane->translate(
QPointF(dimX.
end, calcMeanValue)));
340 plane->translate(
QPointF(dimX.
end, calcMeanValue + 2 * calcStandardDeviation)));
342 plane->translate(
QPointF(dimX.
end, calcMeanValue + 3 * calcStandardDeviation)));
344 plane->translate(
QPointF(dimX.
end, calcMeanValue - 2 * calcStandardDeviation)));
346 plane->translate(
QPointF(dimX.
end, calcMeanValue - 3 * calcStandardDeviation)));
static void calculateSteps(qreal start_, qreal end_, const QList< qreal > &list, int minSteps, int maxSteps, int power, qreal &steps, qreal &stepWidth, bool adjustLower, bool adjustUpper)
@ GranularitySequence_125_25
@ GranularitySequence_25_50
@ GranularitySequenceIrregular
@ GranularitySequence_10_20
@ GranularitySequence_10_50
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=nullptr)
DataDimensionsList updateData(AbstractCoordinatePlane *plane)
Returns the cached result of data calculation.
DataDimensionsList mDataDimensions
AbstractCoordinatePlane * mPlane
static void adjustLowerUpperRange(qreal &start, qreal &end, qreal stepWidth, bool adjustLower, bool adjustUpper)
static bool isBoundariesValid(const QRectF &r)
Helper class for one dimension of data, e.g. for the rows in a data model, or for the labels of an ax...
Levey Jennings coordinate plane This is actually nothing real more than a plain cartesian coordinate ...
A set of attributes controlling the appearance of grids.
bool isGridVisible(GridType type) const
QPen gridPen(GridType type) const
QBrush rangeBrush(Range range) const
void drawGrid(PaintContext *context) override
Stores information about painting diagrams.
AbstractCoordinatePlane * coordinatePlane() const
QPainter * painter() const
const T & at(int i) const const
int count(const T &value) const const
void drawLine(const QLineF &line)
void fillRect(const QRectF &rectangle, const QBrush &brush)
void setPen(const QColor &color)