1 /*
2 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "KChartAbstractGrid.h"
21 #include "KChartPaintContext.h"
22
23 #include "KChartMath_p.h"
24
25 #include <qglobal.h>
26
27
28 using namespace KChart;
29 using namespace std;
30
31
_trunc(qreal v)32 static qreal _trunc( qreal v )
33 {
34 return (( v > 0.0 ) ? floor( v ) : ceil( v ));
35 }
36
37
AbstractGrid()38 AbstractGrid::AbstractGrid ()
39 : mPlane( nullptr )
40 {
41 //this bloc left empty intentionally
42 }
43
~AbstractGrid()44 AbstractGrid::~AbstractGrid()
45 {
46 //this bloc left empty intentionally
47 }
48
setNeedRecalculate()49 void AbstractGrid::setNeedRecalculate()
50 {
51 mCachedRawDataDimensions.clear();
52 }
53
updateData(AbstractCoordinatePlane * plane)54 DataDimensionsList AbstractGrid::updateData( AbstractCoordinatePlane* plane )
55 {
56 if ( plane ) {
57 const DataDimensionsList rawDataDimensions( plane->getDataDimensionsList() );
58 // ### this could be dangerous becaus calculateGrid() looks at some data we are not checking
59 // for changes here.
60 if ( mCachedRawDataDimensions.empty() || ( rawDataDimensions != mCachedRawDataDimensions ) ) {
61 mCachedRawDataDimensions = rawDataDimensions;
62 mPlane = plane;
63 mDataDimensions = calculateGrid( rawDataDimensions );
64 }
65 }
66 return mDataDimensions;
67 }
68
isBoundariesValid(const QRectF & r)69 bool AbstractGrid::isBoundariesValid(const QRectF& r )
70 {
71 return isBoundariesValid( qMakePair( r.topLeft(), r.bottomRight() ) );
72 }
73
isBoundariesValid(const QPair<QPointF,QPointF> & b)74 bool AbstractGrid::isBoundariesValid(const QPair<QPointF,QPointF>& b )
75 {
76 return isValueValid( b.first.x() ) && isValueValid( b.first.y() ) &&
77 isValueValid( b.second.x() ) && isValueValid( b.second.y() );
78 }
79
isBoundariesValid(const DataDimensionsList & l)80 bool AbstractGrid::isBoundariesValid(const DataDimensionsList& l )
81 {
82 for (int i = 0; i < l.size(); ++i)
83 if ( ! isValueValid( l.at(i).start ) || ! isValueValid( l.at(i).end ) )
84 return false;
85 return true;
86 }
87
isValueValid(const qreal & r)88 bool AbstractGrid::isValueValid(const qreal& r )
89 {
90 return !(ISNAN(r) || ISINF(r));
91 }
92
adjustLowerUpperRange(qreal & start,qreal & end,qreal stepWidth,bool adjustLower,bool adjustUpper)93 void AbstractGrid::adjustLowerUpperRange(
94 qreal& start, qreal& end,
95 qreal stepWidth,
96 bool adjustLower, bool adjustUpper )
97 {
98 const qreal startAdjust = ( start >= 0.0 ) ? 0.0 : -1.0;
99 const qreal endAdjust = ( end >= 0.0 ) ? 1.0 : 0.0;
100 if ( adjustLower && !qFuzzyIsNull( fmod( start, stepWidth ) ) )
101 start = stepWidth * (_trunc( start / stepWidth ) + startAdjust);
102 if ( adjustUpper && !qFuzzyIsNull( fmod( end, stepWidth ) ) )
103 end = stepWidth * (_trunc( end / stepWidth ) + endAdjust);
104 }
105
adjustedLowerUpperRange(const DataDimension & dim,bool adjustLower,bool adjustUpper)106 const DataDimension AbstractGrid::adjustedLowerUpperRange(
107 const DataDimension& dim,
108 bool adjustLower, bool adjustUpper )
109 {
110 DataDimension result( dim );
111 adjustLowerUpperRange(
112 result.start, result.end,
113 result.stepWidth,
114 adjustLower, adjustUpper );
115 return result;
116 }
117