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();
49 const DataDimension dimX = calculateGridXY(l.first(), Qt::Horizontal,
false,
false);
52 const DataDimension minMaxY = calculateGridXY(l.last(), Qt::Vertical,
false,
false);
54 if (plane->autoAdjustGridToZoom()
56 && plane->zoomFactorY() > 1.0) {
57 l.last().start = translatedBottomLeft.y();
58 l.last().end = translatedTopRight.y();
61 const DataDimension dimY = calculateGridXY(l.last(), Qt::Vertical,
false,
false);
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))
93 Qt::Orientation orientation,
94 bool adjustLower,
bool adjustUpper)
const
97 if (dim.isCalculated && dim.start != dim.end) {
99 if (dim.stepWidth == 0.0) {
100 QList<qreal> granularities;
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;
133 qreal start_, qreal end_,
const QList<qreal> &list,
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;
168 void LeveyJenningsGrid::calculateStepWidth(
169 qreal start_, qreal end_,
170 const QList<qreal> &granularities,
171 Qt::Orientation orientation,
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.");
179 QList<qreal> list(granularities);
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();
199 QList<qreal> testList;
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));
290 context->
painter()->fillRect(QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())),
294 topLeft = plane->translate(QPointF(dimX.
start, meanValue + 2 * standardDeviation));
295 bottomRight = plane->translate(QPointF(dimX.
end, meanValue + 3 * standardDeviation));
296 context->
painter()->fillRect(QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())),
299 topLeft = plane->translate(QPointF(dimX.
start, meanValue - 2 * standardDeviation));
300 bottomRight = plane->translate(QPointF(dimX.
end, meanValue - 3 * standardDeviation));
301 context->
painter()->fillRect(QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())),
305 topLeft = plane->translate(QPointF(dimX.
start, meanValue + 3 * standardDeviation));
306 bottomRight = plane->translate(QPointF(dimX.
end, meanValue + 4 * standardDeviation));
307 context->
painter()->fillRect(QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())),
310 topLeft = plane->translate(QPointF(dimX.
start, meanValue - 3 * standardDeviation));
311 bottomRight = plane->translate(QPointF(dimX.
end, meanValue - 4 * standardDeviation));
312 context->
painter()->fillRect(QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y())),
318 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue)),
319 plane->translate(QPointF(dimX.
end, meanValue)));
320 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue + 2 * standardDeviation)),
321 plane->translate(QPointF(dimX.
end, meanValue + 2 * standardDeviation)));
322 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue + 3 * standardDeviation)),
323 plane->translate(QPointF(dimX.
end, meanValue + 3 * standardDeviation)));
324 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue + 4 * standardDeviation)),
325 plane->translate(QPointF(dimX.
end, meanValue + 4 * standardDeviation)));
326 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue - 2 * standardDeviation)),
327 plane->translate(QPointF(dimX.
end, meanValue - 2 * standardDeviation)));
328 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue - 3 * standardDeviation)),
329 plane->translate(QPointF(dimX.
end, meanValue - 3 * standardDeviation)));
330 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, meanValue - 4 * standardDeviation)),
331 plane->translate(QPointF(dimX.
end, meanValue - 4 * standardDeviation)));
337 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, calcMeanValue)),
338 plane->translate(QPointF(dimX.
end, calcMeanValue)));
339 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, calcMeanValue + 2 * calcStandardDeviation)),
340 plane->translate(QPointF(dimX.
end, calcMeanValue + 2 * calcStandardDeviation)));
341 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, calcMeanValue + 3 * calcStandardDeviation)),
342 plane->translate(QPointF(dimX.
end, calcMeanValue + 3 * calcStandardDeviation)));
343 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, calcMeanValue - 2 * calcStandardDeviation)),
344 plane->translate(QPointF(dimX.
end, calcMeanValue - 2 * calcStandardDeviation)));
345 context->
painter()->drawLine(plane->translate(QPointF(dimX.
start, calcMeanValue - 3 * 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
QList< DataDimension > DataDimensionsList