9#include "KChartCartesianAxis.h"
10#include "KChartCartesianAxis_p.h"
18#include <QApplication>
20#include "KChartPaintContext.h"
21#include "KChartChart.h"
22#include "KChartAbstractCartesianDiagram.h"
23#include "KChartAbstractDiagram_p.h"
24#include "KChartAbstractGrid.h"
25#include "KChartPainterSaver_p.h"
26#include "KChartLayoutItems.h"
27#include "KChartBarDiagram.h"
28#include "KChartStockDiagram.h"
29#include "KChartLineDiagram.h"
30#include "KChartPrintingParameters.h"
36static qreal slightlyLessThan( qreal r )
40 return r - std::numeric_limits< qreal >::epsilon() * 1e-6;
43 qreal diff = qAbs( r ) * std::numeric_limits< qreal >::epsilon() * 2.0;
47static int numSignificantDecimalPlaces( qreal floatNumber )
49 static const int maxPlaces = 15;
52 for ( ; ret > 0; ret-- ) {
66static const T& constify(T &v)
74 m_majorThinningFactor( majorThinningFactor ),
75 m_majorLabelCount( 0 ),
79 const CartesianAxis::Private *axisPriv = CartesianAxis::Private::get( a );
80 XySwitch xy( axisPriv->isVertical() );
85 m_dimension.end -= m_dimension.stepWidth;
88 m_annotations = axisPriv->annotations;
89 m_customTicks = axisPriv->customTicksPositions;
91 const qreal inf = std::numeric_limits< qreal >::infinity();
93 if ( m_customTicks.count() ) {
94 std::sort(m_customTicks.begin(), m_customTicks.end());
95 m_customTickIndex = 0;
96 m_customTick = m_customTicks.at( m_customTickIndex );
98 m_customTickIndex = -1;
102 if ( m_majorThinningFactor > 1 && hasShorterLabels() ) {
103 m_manualLabelTexts = m_axis->shortLabels();
105 m_manualLabelTexts = m_axis->labels();
107 m_manualLabelIndex = m_manualLabelTexts.isEmpty() ? -1 : 0;
109 if ( !m_dimension.isCalculated ) {
118 if ( !dataHeaderLabels.
isEmpty() ) {
121 if ( anchorCount == dataHeaderLabels.
count() ) {
122 for (
int i = 0; i < anchorCount; i++ ) {
124 m_dataHeaderLabels.insert( qreal( i ), dataHeaderLabels.
at( i ) );
130 bool hasMajorTicks = m_axis->rulerAttributes().showMajorTickMarks();
131 bool hasMinorTicks = m_axis->rulerAttributes().showMinorTickMarks();
133 init( xy.isY, hasMajorTicks, hasMinorTicks, plane );
139 const auto diagrams = plane->
diagrams();
145 const auto axes = cd->
axes();
147 const CartesianAxis::Private *axisPriv = CartesianAxis::Private::get( axis );
148 if ( axisPriv->isVertical() == isY ) {
149 annotations.
insert( axisPriv->annotations );
156TickIterator::TickIterator(
bool isY,
const DataDimension& dimension,
bool useAnnotationsForTicks,
159 m_dimension( dimension ),
160 m_majorThinningFactor( 1 ),
161 m_majorLabelCount( 0 ),
162 m_customTickIndex( -1 ),
163 m_manualLabelIndex( -1 ),
165 m_customTick( std::numeric_limits< qreal >::infinity() )
167 if ( useAnnotationsForTicks ) {
168 m_annotations = allAxisAnnotations( plane, isY );
170 init( isY, hasMajorTicks, hasMinorTicks, plane );
173void TickIterator::init(
bool isY,
bool hasMajorTicks,
bool hasMinorTicks,
176 Q_ASSERT( std::numeric_limits< qreal >::has_infinity );
178 m_isLogarithmic = m_dimension.calcMode == AbstractCoordinatePlane::Logarithmic;
180 hasMajorTicks = hasMajorTicks && ( m_dimension.stepWidth > 0 || m_isLogarithmic );
181 hasMinorTicks = hasMinorTicks && ( m_dimension.subStepWidth > 0 || m_isLogarithmic );
186 m_isLogarithmic = m_dimension.calcMode == AbstractCoordinatePlane::Logarithmic;
187 if ( !m_isLogarithmic ) {
193 const bool adjustLower = gridAttributes.adjustLowerBoundToGrid() && !fixedRange;
194 const bool adjustUpper = gridAttributes.adjustUpperBoundToGrid() && !fixedRange;
197 m_decimalPlaces = numSignificantDecimalPlaces( m_dimension.stepWidth );
200 m_decimalPlaces = -1;
203 const qreal inf = std::numeric_limits< qreal >::infinity();
207 if ( m_isLogarithmic ) {
208 if ( ISNAN( m_dimension.start ) || ISNAN( m_dimension.end ) ) {
211 m_dimension.start = 0.0;
212 m_dimension.end = 0.0;
216 }
else if ( m_dimension.start >= 0 ) {
217 m_position = m_dimension.start ? pow( 10.0, floor( log10( m_dimension.start ) ) - 1.0 )
219 m_majorTick = hasMajorTicks ? m_position : inf;
220 m_minorTick = hasMinorTicks ? m_position * 20.0 : inf;
222 m_position = -pow( 10.0, ceil( log10( -m_dimension.start ) ) + 1.0 );
223 m_majorTick = hasMajorTicks ? m_position : inf;
224 m_minorTick = hasMinorTicks ? m_position * 0.09 : inf;
227 m_majorTick = hasMajorTicks ? m_dimension.start : inf;
228 m_minorTick = hasMinorTicks ? m_dimension.start : inf;
229 m_position = slightlyLessThan( m_dimension.start );
235bool TickIterator::areAlmostEqual( qreal r1, qreal r2 )
const
237 if ( !m_isLogarithmic ) {
238 qreal span = m_dimension.end - m_dimension.start;
242 span = qFuzzyIsNull( m_dimension.start) ? 1 : qAbs( m_dimension.start );
244 return qAbs( r2 - r1 ) < ( span ) * 1e-6;
246 return qAbs( r2 - r1 ) < qMax( qAbs( r1 ), qAbs( r2 ) ) * 0.01;
250bool TickIterator::isHigherPrecedence( qreal importantTick, qreal unimportantTick )
const
252 return importantTick != std::numeric_limits< qreal >::infinity() &&
253 ( importantTick <= unimportantTick || areAlmostEqual( importantTick, unimportantTick ) );
256void TickIterator::computeMajorTickLabel(
int decimalPlaces )
258 if ( m_manualLabelIndex >= 0 ) {
259 m_text = m_manualLabelTexts[ m_manualLabelIndex++ ];
260 if ( m_manualLabelIndex >= m_manualLabelTexts.count() ) {
262 m_manualLabelIndex = 0;
264 m_type = m_majorThinningFactor > 1 ? MajorTickManualShort : MajorTickManualLong;
267 if ( m_axis && ( m_majorLabelCount++ % m_majorThinningFactor ) == 0 ) {
269 constify(m_dataHeaderLabels).lowerBound( slightlyLessThan( m_position ) );
271 if ( it != m_dataHeaderLabels.constEnd() && areAlmostEqual( it.
key(), m_position ) ) {
273 m_type = MajorTickHeaderDataLabel;
276 if ( decimalPlaces < 0 ) {
289void TickIterator::operator++()
294 const qreal inf = std::numeric_limits< qreal >::infinity();
298 if ( !m_annotations.isEmpty() ) {
300 if ( it != m_annotations.constEnd() ) {
301 m_position = it.
key();
307 }
else if ( !m_isLogarithmic && m_dimension.stepWidth * 1e6 <
308 qMax( qAbs( m_dimension.start ), qAbs( m_dimension.end ) ) ) {
316 if ( m_isLogarithmic ) {
317 while ( m_majorTick <= m_position ) {
318 m_majorTick *= m_position >= 0 ? 10 : 0.1;
320 while ( m_minorTick <= m_position ) {
322 m_minorTick += m_majorTick * ( m_position >= 0 ? 0.1 : 1.0 );
325 while ( m_majorTick <= m_position ) {
326 m_majorTick += m_dimension.stepWidth;
328 while ( m_minorTick <= m_position ) {
329 m_minorTick += m_dimension.subStepWidth;
333 while ( m_customTickIndex >= 0 && m_customTick <= m_position ) {
334 if ( ++m_customTickIndex >= m_customTicks.count() ) {
335 m_customTickIndex = -1;
339 m_customTick = m_customTicks.at( m_customTickIndex );
343 if ( isHigherPrecedence( m_customTick, m_majorTick ) && isHigherPrecedence( m_customTick, m_minorTick ) ) {
344 m_position = m_customTick;
345 computeMajorTickLabel( -1 );
348 if ( m_type == MajorTick ) {
351 }
else if ( isHigherPrecedence( m_majorTick, m_minorTick ) ) {
352 m_position = m_majorTick;
353 if ( m_minorTick != inf ) {
355 m_minorTick = m_majorTick;
357 computeMajorTickLabel( m_decimalPlaces );
358 }
else if ( m_minorTick != inf ) {
359 m_position = m_minorTick;
367 if ( m_position > m_dimension.end || ISNAN( m_position ) ) {
375 :
AbstractAxis ( new Private( diagram, this ), diagram )
380CartesianAxis::~CartesianAxis()
384 while ( d->mDiagram ) {
388 for (
AbstractDiagram *diagram : std::as_const(d->secondaryDiagrams) ) {
394void CartesianAxis::init()
396 d->customTickLength = 3;
397 d->position = Bottom;
398 setCachedSizeDirty();
399 connect(
this, SIGNAL(coordinateSystemChanged()), SLOT(slotCoordinateSystemChanged()) );
405 if ( other ==
this ) {
412 ( titleText() == other->titleText() ) &&
416void CartesianAxis::slotCoordinateSystemChanged()
424 setCachedSizeDirty();
428QString CartesianAxis::titleText()
const
433void CartesianAxis::setTitleTextAttributes(
const TextAttributes &a )
435 d->titleTextAttributes = a;
436 d->useDefaultTextAttributes =
false;
437 setCachedSizeDirty();
443 if ( hasDefaultTitleTextAttributes() ) {
446 me.setValue( me.value() * 1.5 );
450 return d->titleTextAttributes;
455 d->useDefaultTextAttributes =
true;
456 setCachedSizeDirty();
460bool CartesianAxis::hasDefaultTitleTextAttributes()
const
462 return d->useDefaultTextAttributes;
465void CartesianAxis::setPosition(
Position p )
467 if ( d->position == p ) {
474 setCachedSizeDirty();
478#if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
481CartesianAxis::Position CartesianAxis::position()
const
486void CartesianAxis::layoutPlanes()
488 if ( ! d->diagram() || ! d->diagram()->coordinatePlane() ) {
497static bool referenceDiagramIsBarDiagram(
const AbstractDiagram * diagram )
500 qobject_cast< const AbstractCartesianDiagram * >( diagram );
503 return qobject_cast< const BarDiagram* >( dia ) !=
nullptr;
506static bool referenceDiagramNeedsCenteredAbscissaTicks(
const AbstractDiagram *diagram )
509 qobject_cast< const AbstractCartesianDiagram * >( diagram );
512 if ( qobject_cast< const BarDiagram* >( dia ) )
514 if ( qobject_cast< const StockDiagram* >( dia ) )
517 const LineDiagram * lineDiagram = qobject_cast< const LineDiagram* >( dia );
521bool CartesianAxis::isAbscissa()
const
523 const Qt::Orientation diagramOrientation = referenceDiagramIsBarDiagram( d->diagram() ) ? ( (
BarDiagram* )( d->diagram() ) )->orientation()
525 return diagramOrientation ==
Qt::Vertical ? position() == Bottom || position() == Top
526 : position() == Left || position() == Right;
529bool CartesianAxis::isOrdinate()
const
531 return !isAbscissa();
536 if ( !d->diagram() || !d->diagram()->coordinatePlane() ) {
540 ctx.setPainter ( painter );
542 ctx.setCoordinatePlane( plane );
545 PainterSaver painterSaver( painter );
550 if ( zoomFactor > 1.0 ) {
552 d->amountOfRightOverlap + 1, d->amountOfBottomOverlap + 1 ) );
557const TextAttributes CartesianAxis::Private::titleTextAttributesWithAdjustedRotation()
const
560 int rotation = titleTA.rotation();
561 if ( position == Left || position == Right ) {
564 if ( rotation >= 360 ) {
568 rotation = ( rotation / 90 ) * 90;
569 titleTA.setRotation( rotation );
579 diagram()->
unitSuffix(
int( value ), orientation,
true );
580 return axis()->customizedLabel( withUnits );
585 d->axisTitleSpace = axisTitleSpace;
590 return d->axisTitleSpace;
606 const QRect& geoRect )
const
608 const TextAttributes titleTA( titleTextAttributesWithAdjustedRotation() );
609 if ( titleTA.isVisible() ) {
610 TextLayoutItem titleItem( titleText, titleTA, plane->parent(), KChartEnums::MeasureOrientationMinimum,
613 QSize size = titleItem.sizeHint();
614 switch ( position ) {
617 point.
setY( geoRect.
top() + ( size.
height() / 2 ) / axisTitleSpace );
618 size.
setWidth( qMin( size.
width(), axis()->geometry().width() ) );
623 size.
setWidth( qMin( size.
width(), axis()->geometry().width() ) );
626 point.
setX( geoRect.
left() + ( size.
width() / 2 ) / axisTitleSpace );
631 point.
setX( geoRect.
right() - ( size.
width() / 2 ) / axisTitleSpace );
636 const PainterSaver painterSaver( painter );
640 titleItem.paint( painter );
644bool CartesianAxis::Private::isVertical()
const
646 return axis()->isAbscissa() == AbstractDiagram::Private::get( diagram() )->isTransposed();
651 Q_ASSERT_X ( d->diagram(),
"CartesianAxis::paint",
652 "Function call not allowed: The axis is not assigned to any diagram." );
655 Q_ASSERT_X ( plane,
"CartesianAxis::paint",
656 "Bad function call: PaintContext::coordinatePlane() NOT a cartesian plane." );
660 if ( !d->diagram()->model() ) {
664 const bool centerTicks = referenceDiagramNeedsCenteredAbscissaTicks( d->diagram() ) && isAbscissa();
666 XySwitch geoXy( d->isVertical() );
668 QPainter*
const painter = context->painter();
672 qreal transversePosition = signalingNaN;
675 qreal transverseScreenSpaceShift = signalingNaN;
682 QPointF end( dimX.end, dimY.end );
685 switch ( position() ) {
686 case CartesianAxis::Bottom:
687 end.setY( dimY.start );
689 case CartesianAxis::Top:
690 start.setY( dimY.end );
692 case CartesianAxis::Left:
693 end.setX( dimX.start );
695 case CartesianAxis::Right:
696 start.setX( dimX.end );
700 transversePosition = geoXy(
start.y(),
start.x() );
709 switch ( position() ) {
710 case CartesianAxis::Bottom:
711 transverseScreenSpaceShift = geo.top() - transStart.
y();
713 case CartesianAxis::Top:
714 transverseScreenSpaceShift = geo.bottom() - transStart.
y();
716 case CartesianAxis::Left:
717 transverseScreenSpaceShift = geo.right() - transStart.
x();
719 case CartesianAxis::Right:
720 transverseScreenSpaceShift = geo.left() - transStart.
x();
724 geoXy.lvalue( transStart.
ry(), transStart.
rx() ) += transverseScreenSpaceShift;
725 geoXy.lvalue( transEnd.
ry(), transEnd.
rx() ) += transverseScreenSpaceShift;
731 painter->
drawLine( transStart, transEnd );
741 int labelThinningFactor = 1;
753 for (
int step = labelTA.
isVisible() ? Layout : Painting; step < Done; step++ ) {
754 bool skipFirstTick = !rulerAttr.showFirstTick();
755 bool isFirstLabel =
true;
756 for ( TickIterator it(
this, plane, labelThinningFactor, centerTicks ); !it.isAtEnd(); ++it ) {
757 if ( skipFirstTick ) {
758 skipFirstTick =
false;
762 const qreal drawPos = it.position() + ( centerTicks ? 0.5 : 0. );
764 QPointF( transversePosition, drawPos ) ) );
765 geoXy.lvalue( onAxis.
ry(), onAxis.
rx() ) += transverseScreenSpaceShift;
766 const bool isOutwardsPositive = position() == Bottom || position() == Right;
771 qreal tickLen = it.type() == TickIterator::CustomTick ?
772 d->customTickLength : tickLength( it.type() == TickIterator::MinorTick );
773 geoXy.lvalue( tickEnd.
ry(), tickEnd.
rx() ) += isOutwardsPositive ? tickLen : -tickLen;
776 if ( position() == Top ) {
779 }
else if ( position() == Left ) {
783 if ( step == Painting ) {
785 if ( rulerAttr.hasTickMarkPenAt( it.position() ) ) {
786 painter->
setPen( rulerAttr.tickMarkPen( it.position() ) );
788 painter->
setPen( it.type() == TickIterator::MinorTick ? rulerAttr.minorTickMarkPen()
789 : rulerAttr.majorTickMarkPen() );
791 painter->
drawLine( onAxis, tickEnd );
803 if ( it.type() == TickIterator::MajorTick ) {
806 }
else if ( it.type() == TickIterator::MajorTickHeaderDataLabel ) {
811 tickLabel->setText( text );
813 QPolygon labelPoly = tickLabel->boundingPolygon();
814 Q_ASSERT( labelPoly.
count() == 4 );
819 switch ( position() ) {
821 axisAngle = 0;
break;
823 axisAngle = 180;
break;
825 axisAngle = 270;
break;
827 axisAngle = 90;
break;
834 int relAngle = axisAngle - labelTA.
rotation() + 45;
835 if ( relAngle < 0 ) {
838 int polyCorner1 = relAngle / 90;
839 QPoint p1 = labelPoly.
at( polyCorner1 );
840 QPoint p2 = labelPoly.
at( polyCorner1 == 3 ? 0 : ( polyCorner1 + 1 ) );
844 qreal labelMargin = rulerAttr.labelMargin();
845 if ( labelMargin < 0 ) {
848 labelMargin -= tickLabel->marginWidth();
850 switch ( position() ) {
853 -0.45 * size.
height() - 0.5 * ( p1.
y() + p2.
y() ) );
856 labelPos +=
QPointF( labelMargin,
857 -0.45 * size.
height() - 0.5 * ( p1.
y() + p2.
y() ) );
860 labelPos +=
QPointF( -0.45 * size.
width() - 0.5 * ( p1.
x() + p2.
x() ),
861 -size.
height() - labelMargin );
864 labelPos +=
QPointF( -0.45 * size.
width() - 0.5 * ( p1.
x() + p2.
x() ),
871 if ( step == Painting ) {
872 tickLabel->paint( painter );
880 if ( step == Layout ) {
881 int spaceSavingRotation = geoXy( 270, 0 );
883 const bool canShortenLabels = !geoXy.isY && it.type() == TickIterator::MajorTickManualLong &&
884 it.hasShorterLabels();
885 bool collides =
false;
886 if ( it.type() == TickIterator::MajorTick || it.type() == TickIterator::MajorTickHeaderDataLabel
887 || canShortenLabels || canRotate ) {
888 if ( isFirstLabel ) {
889 isFirstLabel =
false;
891 collides = tickLabel->intersects( *prevTickLabel, labelPos, prevTickLabelPos );
892 qSwap( prevTickLabel, tickLabel );
894 prevTickLabelPos = labelPos;
898 if ( canRotate && !canShortenLabels ) {
903 labelThinningFactor++;
913 delete prevTickLabel;
914 prevTickLabel =
nullptr;
916 if ( ! titleText().
isEmpty() ) {
917 d->drawTitleText( painter, plane,
geometry() );
931 switch ( position() ) {
947void CartesianAxis::setCachedSizeDirty()
const
949 d->cachedMaximumSize =
QSize();
955 if ( ! d->cachedMaximumSize.isValid() )
956 d->cachedMaximumSize = d->calculateMaximumSize();
957 return d->cachedMaximumSize;
960QSize CartesianAxis::Private::calculateMaximumSize()
const
968 QObject* refArea = plane->parent();
969 const bool centerTicks = referenceDiagramNeedsCenteredAbscissaTicks( diagram() )
970 && axis()->isAbscissa();
978 XySwitch geoXy( isVertical() );
983 qreal startOverhang = 0.0;
984 qreal endOverhang = 0.0;
986 if ( mAxis->textAttributes().isVisible() ) {
988 qreal lowestLabelPosition = signalingNaN;
989 qreal highestLabelPosition = signalingNaN;
990 qreal lowestLabelLongitudinalSize = signalingNaN;
991 qreal highestLabelLongitudinalSize = signalingNaN;
997 bool showFirstTick = rulerAttr.showFirstTick();
998 for ( TickIterator it( axis(), plane, 1, centerTicks ); !it.isAtEnd(); ++it ) {
999 const qreal drawPos = it.position() + ( centerTicks ? 0.5 : 0. );
1000 if ( !showFirstTick ) {
1001 showFirstTick =
true;
1005 qreal labelSizeTransverse = 0.0;
1006 qreal labelMargin = 0.0;
1010 geoXy( qreal(1.0), drawPos ) ) );
1011 highestLabelPosition = geoXy( labelPosition.
x(), labelPosition.
y() );
1013 if ( it.type() == TickIterator::MajorTick ) {
1016 }
else if ( it.type() == TickIterator::MajorTickHeaderDataLabel ) {
1018 text = axis()->customizedLabel( text );
1020 tickLabel.setText( text );
1022 QSize sz = tickLabel.sizeHint();
1023 highestLabelLongitudinalSize = geoXy( sz.
width(), sz.
height() );
1024 if ( ISNAN( lowestLabelLongitudinalSize ) ) {
1025 lowestLabelLongitudinalSize = highestLabelLongitudinalSize;
1026 lowestLabelPosition = highestLabelPosition;
1029 labelSizeTransverse = geoXy( sz.
height(), sz.
width() );
1030 labelMargin = rulerAttr.labelMargin();
1031 if ( labelMargin < 0 ) {
1034 labelMargin -= tickLabel.marginWidth();
1036 qreal tickLength = it.type() == TickIterator::CustomTick ?
1037 customTickLength : axis()->tickLength( it.type() == TickIterator::MinorTick );
1038 size = qMax( size, tickLength + labelMargin + labelSizeTransverse );
1045 const qreal lowestPosition = geoXy( pt.
x(), pt.
y() );
1047 const qreal highestPosition = geoXy( pt.
x(), pt.
y() );
1050 startOverhang = qMax( 0.0, ( lowestPosition - lowestLabelPosition ) * geoXy( 1.0, -1.0 ) +
1051 lowestLabelLongitudinalSize * 0.5 );
1052 endOverhang = qMax( 0.0, ( highestLabelPosition - highestPosition ) * geoXy( 1.0, -1.0 ) +
1053 highestLabelLongitudinalSize * 0.5 );
1056 amountOfLeftOverlap = geoXy( startOverhang, qreal(0.0) );
1057 amountOfRightOverlap = geoXy( endOverhang, qreal(0.0) );
1058 amountOfBottomOverlap = geoXy( qreal(0.0), startOverhang );
1059 amountOfTopOverlap = geoXy( qreal(0.0), endOverhang );
1061 const TextAttributes titleTA = titleTextAttributesWithAdjustedRotation();
1062 if ( titleTA.
isVisible() && !axis()->titleText().isEmpty() ) {
1063 TextLayoutItem title( axis()->titleText(), titleTA, refArea, KChartEnums::MeasureOrientationMinimum,
1067 size += geoXy( titleFM.height() * 0.33, titleFM.averageCharWidth() * 0.55 );
1068 size += geoXy( title.sizeHint().height(), title.sizeHint().width() );
1072 return QSize( geoXy( 1,
int( size ) ), geoXy(
int ( size ), 1 ) );
1090 if ( d->geometry != r ) {
1092 setCachedSizeDirty();
1104 if ( d->customTickLength == value ) {
1107 d->customTickLength = value;
1108 setCachedSizeDirty();
1114 return d->customTickLength;
1117int CartesianAxis::tickLength(
bool subUnitTicks )
const
1120 return subUnitTicks ? rulerAttr.minorTickMarkLength() : rulerAttr.majorTickMarkLength();
1125 return d->annotations;
1134 setCachedSizeDirty();
1140 return d->customTicksPositions;
1145 if ( d->customTicksPositions == customTicksPositions )
1148 d->customTicksPositions = customTicksPositions;
1149 setCachedSizeDirty();
1153#if !defined(QT_NO_DEBUG_STREAM)
1154QDebug operator<<(
QDebug dbg, KChart::CartesianAxis::Position pos)
1157 case KChart::CartesianAxis::Bottom: dbg <<
"KChart::CartesianAxis::Bottom";
break;
1158 case KChart::CartesianAxis::Top: dbg <<
"KChart::CartesianAxis::Top";
break;
1159 case KChart::CartesianAxis::Left: dbg <<
"KChart::CartesianAxis::Left";
break;
1160 case KChart::CartesianAxis::Right: dbg <<
"KChart::CartesianAxis::Right";
break;
1161 default: dbg <<
"KChart::CartesianAxis::Invalid";
break;
QRect areaGeometry() const override
RulerAttributes rulerAttributes() const
Returns the attributes to be used for painting the rulers.
virtual const QString customizedLabel(const QString &label) const
Reimplement this method if you want to adjust axis labels before they are printed.
bool compare(const AbstractAxis *other) const
Returns true if both axes have the same settings.
TextAttributes textAttributes() const
Returns the text attributes to be used for axis labels.
Base class for diagrams based on a cartesian coordianate system.
virtual KChart::CartesianAxisList axes() const
virtual AbstractCartesianDiagram * referenceDiagram() const
virtual void takeAxis(CartesianAxis *axis)
Removes the axis from the diagram, without deleting it.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
void layoutPlanes()
Calling layoutPlanes() on the plane triggers the global KChart::Chart::slotLayoutPlanes()
virtual qreal zoomFactorY() const
AbstractDiagramList diagrams()
AbstractDiagram * diagram()
virtual qreal zoomFactorX() const
DataDimensionsList gridDimensionsList()
Returns the dimensions used for drawing the grid lines.
AbstractDiagram defines the interface for diagram classes.
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
QString unitPrefix(int column, Qt::Orientation orientation, bool fallback=false) const
Retrieves the axis unit prefix for a specific column.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
QStringList itemRowLabels() const
The set of item row labels currently displayed, for use in Abscissa axes, etc.
QString unitSuffix(int column, Qt::Orientation orientation, bool fallback=false) const
Retrieves the axis unit suffix for a specific column.
static const DataDimension adjustedLowerUpperRange(const DataDimension &dim, bool adjustLower, bool adjustUpper)
Adjusts dim so that dim.start and/or dim.end are a multiple of dim.stepWidth.
A proxy model used for decorating data with attributes.
int rowCount(const QModelIndex &) const override
\reimpl
BarDiagram defines a common bar diagram.
The class for cartesian axes.
void resetTitleTextAttributes()
Reset the title text attributes to the built-in default:
bool isEmpty() const override
pure virtual in QLayoutItem
void setCustomTickLength(int value)
Sets the length of custom ticks on the axis.
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
QSize maximumSize() const override
pure virtual in QLayoutItem
QList< qreal > customTicks() const
Returns the currently set custom ticks on the axis.
QMap< qreal, QString > annotations() const
Returns the currently set axis annotations.
CartesianAxis(AbstractCartesianDiagram *diagram=nullptr)
C'tor of the class for cartesian axes.
int customTickLength() const
Returns the length of custom ticks on the axis.
void paintCtx(PaintContext *) override
reimpl
QSize sizeHint() const override
pure virtual in QLayoutItem
QSize minimumSize() const override
pure virtual in QLayoutItem
Qt::Orientations expandingDirections() const override
pure virtual in QLayoutItem
bool compare(const CartesianAxis *other) const
Returns true if both axes have the same settings.
QRect geometry() const override
pure virtual in QLayoutItem
TextAttributes titleTextAttributes() const
Returns the text attributes that will be used for displaying the title text.
void paint(QPainter *) override
reimpl
void setTitleText(const QString &text)
Sets the optional text displayed as axis title.
void setCustomTicks(const QList< qreal > &ticksPostions)
Sets custom ticks on the axis.
void setAnnotations(const QMap< qreal, QString > &annotations)
Sets the axis annotations to annotations.
void setTitleSpace(qreal value)
void setTitleSize(qreal value)
use setTitleTextAttributes() instead
Cartesian coordinate plane.
unsigned int autoAdjustVerticalRangeToData() const
Returns the maximal allowed percent of the vertical space covered by the coordinate plane that may be...
unsigned int autoAdjustHorizontalRangeToData() const
Returns the maximal allowed percent of the horizontal space covered by the coordinate plane that may ...
const QPointF translate(const QPointF &diagramPoint) const override
Translate the given point in value space coordinates to a position in pixel space.
const GridAttributes gridAttributes(Qt::Orientation orientation) const
Helper class for one dimension of data, e.g.
static QPaintDevice * paintDevice()
Return the paint device to use for calculating font metrics.
A set of attributes controlling the appearance of grids.
LineDiagram defines a common line diagram.
bool centerDataPoints() const
Measure is used to specify relative and absolute sizes in KChart, e.g.
Stores information about painting diagrams.
Defines a position, using compass terminology.
A set of attributes controlling the appearance of axis rulers.
A set of text attributes.
void setFontSize(const Measure &measure)
Set the size of the font used for rendering text.
void setRotation(int rotation)
Set the rotation angle to use for the text.
Layout item showing a text.
QSize sizeHint() const override
pure virtual in QLayoutItem
void setTextAttributes(const TextAttributes &a)
Use this to specify the text attributes to be used for this item.
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
Q_SCRIPTABLE Q_NOREPLY void start()
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
int decimalPlaces(const int rangeMax, const int significantFigures)
qreal height() const const
const_reference at(qsizetype i) const const
qsizetype count() const const
bool isEmpty() const const
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
Key key(const T &value, const Key &defaultKey) const const
T value(const Key &key, const T &defaultValue) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
T qobject_cast(QObject *object)
void drawLine(const QLine &line)
void setClipRegion(const QRegion ®ion, Qt::ClipOperation operation)
void setClipping(bool enable)
void setPen(Qt::PenStyle style)
void translate(const QPoint &offset)
QPoint toPoint() const const
void setHeight(int height)
qreal height() const const
QSize toSize() const const
qreal width() const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const