12 #include "KDChartCartesianAxis_p.h"
16 #include <QApplication>
23 #include "KDChartAbstractDiagram_p.h"
30 #include "KDChartPainterSaver_p.h"
34 #include <KDABLibFakes>
44 return r - std::numeric_limits<qreal>::epsilon() * 1e-6;
47 qreal diff = qAbs(r) * std::numeric_limits<qreal>::epsilon() * 2.0;
53 static const int maxPlaces = 15;
54 QString sample = QString::number(floatNumber,
'f', maxPlaces).section(QLatin1Char(
'.'), 1, 2);
56 for (; ret > 0; ret--) {
57 if (sample[ret - 1] != QLatin1Char(
'0')) {
71 , m_majorThinningFactor(majorThinningFactor)
72 , m_majorLabelCount(0)
76 const CartesianAxis::Private *axisPriv = CartesianAxis::Private::get(a);
77 XySwitch xy(axisPriv->isVertical());
82 m_dimension.end -= m_dimension.stepWidth;
85 m_annotations = axisPriv->annotations;
86 m_customTicks = axisPriv->customTicksPositions;
88 const qreal inf = std::numeric_limits<qreal>::infinity();
90 if (m_customTicks.count()) {
91 std::sort(m_customTicks.begin(), m_customTicks.end());
92 m_customTickIndex = 0;
93 m_customTick = m_customTicks.at(m_customTickIndex);
95 m_customTickIndex = -1;
99 if (m_majorThinningFactor > 1 && hasShorterLabels()) {
100 m_manualLabelTexts = m_axis->shortLabels();
102 m_manualLabelTexts = m_axis->labels();
104 m_manualLabelIndex = m_manualLabelTexts.isEmpty() ? -1 : 0;
106 if (!m_dimension.isCalculated) {
112 QStringList dataHeaderLabels;
115 if (!dataHeaderLabels.isEmpty()) {
117 const int anchorCount = model->
rowCount(QModelIndex());
118 if (anchorCount == dataHeaderLabels.count()) {
119 for (
int i = 0; i < anchorCount; i++) {
121 m_dataHeaderLabels.insert(qreal(i), dataHeaderLabels.at(i));
127 bool hasMajorTicks = m_axis->rulerAttributes().showMajorTickMarks();
128 bool hasMinorTicks = m_axis->rulerAttributes().showMinorTickMarks();
130 init(xy.isY, hasMajorTicks, hasMinorTicks, plane);
135 QMultiMap<qreal, QString> annotations;
136 const auto constDiagrams = plane->
diagrams();
138 const auto *cd = qobject_cast<const AbstractCartesianDiagram *>(diagram);
142 const auto axes = cd->axes();
144 const CartesianAxis::Private *axisPriv = CartesianAxis::Private::get(axis);
145 if (axisPriv->isVertical() == isY) {
146 annotations.unite(axisPriv->annotations);
153 TickIterator::TickIterator(
bool isY,
const DataDimension &dimension,
bool useAnnotationsForTicks,
156 , m_dimension(dimension)
157 , m_majorThinningFactor(1)
158 , m_majorLabelCount(0)
159 , m_customTickIndex(-1)
160 , m_manualLabelIndex(-1)
162 , m_customTick(std::numeric_limits<qreal>::infinity())
164 if (useAnnotationsForTicks) {
167 init(isY, hasMajorTicks, hasMinorTicks, plane);
170 void TickIterator::init(
bool isY,
bool hasMajorTicks,
bool hasMinorTicks,
173 Q_ASSERT(std::numeric_limits<qreal>::has_infinity);
175 m_isLogarithmic = m_dimension.calcMode == AbstractCoordinatePlane::Logarithmic;
177 hasMajorTicks = hasMajorTicks && (m_dimension.stepWidth > 0 || m_isLogarithmic);
178 hasMinorTicks = hasMinorTicks && (m_dimension.subStepWidth > 0 || m_isLogarithmic);
183 m_isLogarithmic = m_dimension.calcMode == AbstractCoordinatePlane::Logarithmic;
184 if (!m_isLogarithmic) {
193 m_dimension = AbstractGrid::adjustedLowerUpperRange(m_dimension, adjustLower, adjustUpper);
198 m_decimalPlaces = -1;
201 const qreal inf = std::numeric_limits<qreal>::infinity();
205 if (m_isLogarithmic) {
206 if (ISNAN(m_dimension.start) || ISNAN(m_dimension.end)) {
209 m_dimension.start = 0.0;
210 m_dimension.end = 0.0;
214 }
else if (m_dimension.start >= 0) {
215 m_position = m_dimension.start ? pow(10.0, floor(log10(m_dimension.start)) - 1.0)
217 m_majorTick = hasMajorTicks ? m_position : inf;
218 m_minorTick = hasMinorTicks ? m_position * 20.0 : inf;
220 m_position = -pow(10.0, ceil(log10(-m_dimension.start)) + 1.0);
221 m_majorTick = hasMajorTicks ? m_position : inf;
222 m_minorTick = hasMinorTicks ? m_position * 0.09 : inf;
225 m_majorTick = hasMajorTicks ? m_dimension.start : inf;
226 m_minorTick = hasMinorTicks ? m_dimension.start : inf;
233 bool TickIterator::areAlmostEqual(qreal r1, qreal r2)
const
235 if (!m_isLogarithmic) {
236 qreal span = m_dimension.end - m_dimension.start;
240 span = qFuzzyIsNull(m_dimension.start) ? 1 : qAbs(m_dimension.start);
242 return qAbs(r2 - r1) < (span) * 1e-6;
244 return qAbs(r2 - r1) < qMax(qAbs(r1), qAbs(r2)) * 0.01;
248 bool TickIterator::isHigherPrecedence(qreal importantTick, qreal unimportantTick)
const
250 return importantTick != std::numeric_limits<qreal>::infinity() && (importantTick <= unimportantTick || areAlmostEqual(importantTick, unimportantTick));
253 void TickIterator::computeMajorTickLabel(
int decimalPlaces)
255 if (m_manualLabelIndex >= 0) {
256 m_text = m_manualLabelTexts[m_manualLabelIndex++];
257 if (m_manualLabelIndex >= m_manualLabelTexts.count()) {
259 m_manualLabelIndex = 0;
261 m_type = m_majorThinningFactor > 1 ? MajorTickManualShort : MajorTickManualLong;
264 if (m_axis && (m_majorLabelCount++ % m_majorThinningFactor) == 0) {
268 if (it != m_dataHeaderLabels.constEnd() && areAlmostEqual(it.key(), m_position)) {
270 m_type = MajorTickHeaderDataLabel;
273 if (decimalPlaces < 0) {
276 m_text = QString::number(m_position,
'f', decimalPlaces);
286 void TickIterator::operator++()
291 const qreal inf = std::numeric_limits<qreal>::infinity();
295 if (!m_annotations.isEmpty()) {
296 auto it = m_annotations.upperBound(m_position);
297 if (it != m_annotations.constEnd()) {
298 m_position = it.key();
304 }
else if (!m_isLogarithmic && m_dimension.stepWidth * 1e6 < qMax(qAbs(m_dimension.start), qAbs(m_dimension.end))) {
312 if (m_isLogarithmic) {
313 while (m_majorTick <= m_position) {
314 m_majorTick *= m_position >= 0 ? 10 : 0.1;
316 while (m_minorTick <= m_position) {
318 m_minorTick += m_majorTick * (m_position >= 0 ? 0.1 : 1.0);
321 while (m_majorTick <= m_position) {
322 m_majorTick += m_dimension.stepWidth;
324 while (m_minorTick <= m_position) {
325 m_minorTick += m_dimension.subStepWidth;
329 while (m_customTickIndex >= 0 && m_customTick <= m_position) {
330 if (++m_customTickIndex >= m_customTicks.count()) {
331 m_customTickIndex = -1;
335 m_customTick = m_customTicks.at(m_customTickIndex);
339 if (isHigherPrecedence(m_customTick, m_majorTick) && isHigherPrecedence(m_customTick, m_minorTick)) {
340 m_position = m_customTick;
341 computeMajorTickLabel(-1);
344 if (m_type == MajorTick) {
347 }
else if (isHigherPrecedence(m_majorTick, m_minorTick)) {
348 m_position = m_majorTick;
349 if (m_minorTick != inf) {
351 m_minorTick = m_majorTick;
353 computeMajorTickLabel(m_decimalPlaces);
354 }
else if (m_minorTick != inf) {
355 m_position = m_minorTick;
363 if (m_position > m_dimension.end || ISNAN(m_position)) {
380 while (
d->mDiagram) {
381 auto *cd = qobject_cast<AbstractCartesianDiagram *>(
d->mDiagram);
385 auto *cd = qobject_cast<AbstractCartesianDiagram *>(
diagram);
390 void CartesianAxis::init()
392 d->customTickLength = 3;
409 void CartesianAxis::coordinateSystemChanged()
428 d->titleTextAttributes = a;
429 d->useDefaultTextAttributes =
false;
443 return d->titleTextAttributes;
448 d->useDefaultTextAttributes =
true;
455 return d->useDefaultTextAttributes;
460 if (
d->position == p) {
471 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
482 if (!
d->diagram() || !
d->diagram()->coordinatePlane()) {
494 qobject_cast<const AbstractCartesianDiagram *>(diagram);
495 if (dia && dia->referenceDiagram())
496 dia = dia->referenceDiagram();
497 return qobject_cast<const BarDiagram *>(dia) != 0;
503 qobject_cast<const AbstractCartesianDiagram *>(diagram);
504 if (dia && dia->referenceDiagram())
505 dia = dia->referenceDiagram();
506 if (qobject_cast<const BarDiagram *>(dia))
508 if (qobject_cast<const StockDiagram *>(dia))
511 const auto *lineDiagram = qobject_cast<const LineDiagram *>(dia);
512 return lineDiagram && lineDiagram->centerDataPoints();
530 if (!
d->diagram() || !
d->diagram()->coordinatePlane()) {
539 PainterSaver painterSaver(painter);
544 if (zoomFactor > 1.0) {
545 painter->setClipRegion(
areaGeometry().adjusted(-
d->amountOfLeftOverlap - 1, -
d->amountOfTopOverlap - 1,
546 d->amountOfRightOverlap + 1,
d->amountOfBottomOverlap + 1));
551 const TextAttributes CartesianAxis::Private::titleTextAttributesWithAdjustedRotation()
const
554 int rotation = titleTA.rotation();
555 if (position == Left || position == Right) {
558 if (rotation >= 360) {
562 rotation = (rotation / 90) * 90;
563 titleTA.setRotation(rotation);
567 QString CartesianAxis::Private::customizedLabelText(
const QString &text, Qt::Orientation orientation,
571 QString withUnits = diagram()->unitPrefix(
int(value), orientation,
true) + text + diagram()->unitSuffix(
int(value), orientation,
true);
572 return axis()->customizedLabel(withUnits);
577 d->axisTitleSpace = axisTitleSpace;
582 return d->axisTitleSpace;
598 const QRect &geoRect)
const
600 const TextAttributes titleTA(titleTextAttributesWithAdjustedRotation());
601 if (titleTA.isVisible()) {
603 Qt::AlignHCenter | Qt::AlignVCenter);
605 QSize size = titleItem.sizeHint();
608 point.setX(geoRect.left() + geoRect.width() / 2);
609 point.setY(geoRect.top() + (size.height() / 2) / axisTitleSpace);
610 size.setWidth(qMin(size.width(), axis()->geometry().width()));
613 point.setX(geoRect.left() + geoRect.width() / 2);
614 point.setY(geoRect.bottom() - (size.height() / 2) / axisTitleSpace);
615 size.setWidth(qMin(size.width(), axis()->geometry().width()));
618 point.setX(geoRect.left() + (size.width() / 2) / axisTitleSpace);
619 point.setY(geoRect.top() + geoRect.height() / 2);
620 size.setHeight(qMin(size.height(), axis()->geometry().height()));
623 point.setX(geoRect.right() - (size.width() / 2) / axisTitleSpace);
624 point.setY(geoRect.top() + geoRect.height() / 2);
625 size.setHeight(qMin(size.height(), axis()->geometry().height()));
628 const PainterSaver painterSaver(painter);
629 painter->setClipping(
false);
630 painter->translate(point);
631 titleItem.setGeometry(QRect(QPoint(-size.width() / 2, -size.height() / 2), size));
632 titleItem.paint(painter);
636 bool CartesianAxis::Private::isVertical()
const
638 return axis()->isAbscissa() == AbstractDiagram::Private::get(diagram())->isTransposed();
643 Q_ASSERT_X(
d->diagram(),
"CartesianAxis::paint",
644 "Function call not allowed: The axis is not assigned to any diagram.");
647 Q_ASSERT_X(plane,
"CartesianAxis::paint",
648 "Bad function call: PaintContext::coordinatePlane() NOT a cartesian plane.");
652 if (!
d->diagram()->model()) {
658 XySwitch geoXy(
d->isVertical());
660 QPainter *
const painter = context->
painter();
664 qreal transversePosition = signalingNaN;
667 qreal transverseScreenSpaceShift = signalingNaN;
674 QPointF end(dimX.
end, dimY.
end);
679 end.setY(dimY.
start);
682 start.setY(dimY.
end);
685 end.setX(dimX.
start);
688 start.setX(dimX.
end);
692 transversePosition = geoXy(start.y(), start.x());
694 QPointF transStart = plane->
translate(start);
695 QPointF transEnd = plane->
translate(end);
703 transverseScreenSpaceShift = geo.top() - transStart.y();
706 transverseScreenSpaceShift = geo.bottom() - transStart.y();
709 transverseScreenSpaceShift = geo.right() - transStart.x();
712 transverseScreenSpaceShift = geo.left() - transStart.x();
716 geoXy.lvalue(transStart.ry(), transStart.rx()) += transverseScreenSpaceShift;
717 geoXy.lvalue(transEnd.ry(), transEnd.rx()) += transverseScreenSpaceShift;
720 bool clipSaved = context->
painter()->hasClipping();
721 painter->setClipping(
false);
722 painter->drawLine(transStart, transEnd);
723 painter->setClipping(clipSaved);
732 int labelThinningFactor = 1;
738 QPointF prevTickLabelPos;
745 for (
int step = labelTA.
isVisible() ? Layout : Painting; step < Done; step++) {
747 bool isFirstLabel =
true;
748 for (TickIterator it(
this, plane, labelThinningFactor, centerTicks); !it.isAtEnd(); ++it) {
750 skipFirstTick =
false;
754 const qreal drawPos = it.position() + (centerTicks ? 0.5 : 0.);
755 QPointF onAxis = plane->
translate(geoXy(QPointF(drawPos, transversePosition),
756 QPointF(transversePosition, drawPos)));
757 geoXy.lvalue(onAxis.ry(), onAxis.rx()) += transverseScreenSpaceShift;
762 QPointF tickEnd = onAxis;
763 qreal tickLen = it.type() == TickIterator::CustomTick ?
d->customTickLength :
tickLength(it.type() == TickIterator::MinorTick);
764 geoXy.lvalue(tickEnd.ry(), tickEnd.rx()) += isOutwardsPositive ? tickLen : -tickLen;
774 if (step == Painting) {
777 painter->setPen(rulerAttr.
tickMarkPen(it.position()));
779 painter->setPen(it.type() == TickIterator::MinorTick ? rulerAttr.
minorTickMarkPen()
782 painter->drawLine(onAxis, tickEnd);
786 if (it.text().isEmpty() || !labelTA.
isVisible()) {
793 QString text = it.text();
794 if (it.type() == TickIterator::MajorTick) {
796 text =
d->customizedLabelText(text, geoXy(Qt::Horizontal, Qt::Vertical), it.position());
797 }
else if (it.type() == TickIterator::MajorTickHeaderDataLabel) {
802 tickLabel->setText(text);
803 QSizeF size = QSizeF(tickLabel->sizeHint());
804 QPolygon labelPoly = tickLabel->boundingPolygon();
805 Q_ASSERT(labelPoly.count() == 4);
829 int relAngle = axisAngle - labelTA.
rotation() + 45;
833 int polyCorner1 = relAngle / 90;
834 QPoint p1 = labelPoly.at(polyCorner1);
835 QPoint p2 = labelPoly.at(polyCorner1 == 3 ? 0 : (polyCorner1 + 1));
837 QPointF labelPos = tickEnd;
840 if (labelMargin < 0) {
841 labelMargin = QFontMetricsF(tickLabel->realFont()).height() * 0.5;
843 labelMargin -= tickLabel->marginWidth();
847 labelPos += QPointF(-size.width() - labelMargin,
848 -0.45 * size.height() - 0.5 * (p1.y() + p2.y()));
851 labelPos += QPointF(labelMargin,
852 -0.45 * size.height() - 0.5 * (p1.y() + p2.y()));
855 labelPos += QPointF(-0.45 * size.width() - 0.5 * (p1.x() + p2.x()),
856 -size.height() - labelMargin);
859 labelPos += QPointF(-0.45 * size.width() - 0.5 * (p1.x() + p2.x()),
864 tickLabel->setGeometry(QRect(labelPos.toPoint(), size.toSize()));
866 if (step == Painting) {
867 tickLabel->paint(painter);
875 if (step == Layout) {
876 int spaceSavingRotation = geoXy(270, 0);
878 const bool canShortenLabels = !geoXy.isY && it.type() == TickIterator::MajorTickManualLong && it.hasShorterLabels();
879 bool collides =
false;
880 if (it.type() == TickIterator::MajorTick || it.type() == TickIterator::MajorTickHeaderDataLabel
881 || canShortenLabels || canRotate) {
883 isFirstLabel =
false;
885 collides = tickLabel->intersects(*prevTickLabel, labelPos, prevTickLabelPos);
886 qSwap(prevTickLabel, tickLabel);
888 prevTickLabelPos = labelPos;
892 if (canRotate && !canShortenLabels) {
895 tickLabel->setTextAttributes(labelTA);
897 labelThinningFactor++;
907 delete prevTickLabel;
908 prevTickLabel =
nullptr;
911 d->drawTitleText(painter, plane,
geometry());
924 Qt::Orientations ret;
928 ret = Qt::Horizontal;
943 d->cachedMaximumSize = QSize();
949 if (!
d->cachedMaximumSize.isValid())
950 d->cachedMaximumSize =
d->calculateMaximumSize();
951 return d->cachedMaximumSize;
954 QSize CartesianAxis::Private::calculateMaximumSize()
const
962 QObject *refArea = plane->
parent();
964 && axis()->isAbscissa();
972 XySwitch geoXy(isVertical());
977 qreal startOverhang = 0.0;
978 qreal endOverhang = 0.0;
980 if (mAxis->textAttributes().isVisible()) {
982 qreal lowestLabelPosition = signalingNaN;
983 qreal highestLabelPosition = signalingNaN;
984 qreal lowestLabelLongitudinalSize = signalingNaN;
985 qreal highestLabelLongitudinalSize = signalingNaN;
987 TextLayoutItem tickLabel(QString(), mAxis->textAttributes(), refArea,
992 for (TickIterator it(axis(), plane, 1, centerTicks); !it.isAtEnd(); ++it) {
993 const qreal drawPos = it.position() + (centerTicks ? 0.5 : 0.);
994 if (!showFirstTick) {
995 showFirstTick =
true;
999 qreal labelSizeTransverse = 0.0;
1000 qreal labelMargin = 0.0;
1001 QString text = it.text();
1002 if (!text.isEmpty()) {
1003 QPointF labelPosition = plane->
translate(QPointF(geoXy(drawPos, ( qreal )1.0),
1004 geoXy(( qreal )1.0, drawPos)));
1005 highestLabelPosition = geoXy(labelPosition.x(), labelPosition.y());
1007 if (it.type() == TickIterator::MajorTick) {
1009 text = customizedLabelText(text, geoXy(Qt::Horizontal, Qt::Vertical), it.position());
1010 }
else if (it.type() == TickIterator::MajorTickHeaderDataLabel) {
1012 text = axis()->customizedLabel(text);
1014 tickLabel.setText(text);
1016 QSize sz = tickLabel.sizeHint();
1017 highestLabelLongitudinalSize = geoXy(sz.width(), sz.height());
1018 if (ISNAN(lowestLabelLongitudinalSize)) {
1019 lowestLabelLongitudinalSize = highestLabelLongitudinalSize;
1020 lowestLabelPosition = highestLabelPosition;
1023 labelSizeTransverse = geoXy(sz.height(), sz.width());
1025 if (labelMargin < 0) {
1026 labelMargin = QFontMetricsF(tickLabel.realFont()).height() * 0.5;
1028 labelMargin -= tickLabel.marginWidth();
1030 qreal tickLength = it.type() == TickIterator::CustomTick ? customTickLength : axis()->tickLength(it.type() == TickIterator::MinorTick);
1031 size = qMax(size, tickLength + labelMargin + labelSizeTransverse);
1038 const qreal lowestPosition = geoXy(pt.x(), pt.y());
1040 const qreal highestPosition = geoXy(pt.x(), pt.y());
1043 startOverhang = qMax(0.0, (lowestPosition - lowestLabelPosition) * geoXy(1.0, -1.0) + lowestLabelLongitudinalSize * 0.5);
1044 endOverhang = qMax(0.0, (highestLabelPosition - highestPosition) * geoXy(1.0, -1.0) + highestLabelLongitudinalSize * 0.5);
1047 amountOfLeftOverlap = geoXy(startOverhang, ( qreal )0.0);
1048 amountOfRightOverlap = geoXy(endOverhang, ( qreal )0.0);
1049 amountOfBottomOverlap = geoXy(( qreal )0.0, startOverhang);
1050 amountOfTopOverlap = geoXy(( qreal )0.0, endOverhang);
1052 const TextAttributes titleTA = titleTextAttributesWithAdjustedRotation();
1053 if (titleTA.
isVisible() && !axis()->titleText().isEmpty()) {
1055 Qt::AlignHCenter | Qt::AlignVCenter);
1058 size += geoXy(titleFM.height() * 0.33, titleFM.averageCharWidth() * 0.55);
1059 size += geoXy(title.sizeHint().height(), title.sizeHint().width());
1063 return QSize(geoXy(1,
int(size)), geoXy(
int(size), 1));
1081 if (
d->geometry != r) {
1095 if (
d->customTickLength == value) {
1098 d->customTickLength = value;
1105 return d->customTickLength;
1116 return d->annotations;
1131 return d->customTicksPositions;
1136 if (
d->customTicksPositions == customTicksPositions)
1139 d->customTicksPositions = customTicksPositions;
static QMultiMap< qreal, QString > allAxisAnnotations(const AbstractCoordinatePlane *plane, bool isY)
static int numSignificantDecimalPlaces(qreal floatNumber)
static bool referenceDiagramIsBarDiagram(const AbstractDiagram *diagram)
static qreal slightlyLessThan(qreal r)
static bool referenceDiagramNeedsCenteredAbscissaTicks(const AbstractDiagram *diagram)
@ MeasureOrientationMinimum
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.
const AbstractDiagram * diagram() const
void coordinateSystemChanged()
bool compare(const AbstractAxis *other) const
TextAttributes textAttributes() const
Returns the text attributes to be used for axis labels.
Base class for diagrams based on a cartesian coordianate system.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
virtual qreal zoomFactorY() const
AbstractDiagramList diagrams()
AbstractDiagram * diagram()
DataDimensionsList gridDimensionsList()
virtual qreal zoomFactorX() const
AbstractDiagram defines the interface for diagram classes.
virtual AttributesModel * attributesModel() const
QStringList itemRowLabels() const
A proxy model used for decorating data with attributes.
int rowCount(const QModelIndex &) const override
BarDiagram defines a common bar diagram.
Q_DECL_DEPRECATED qreal titleSpace() const
virtual void setPosition(Position p)
void resetTitleTextAttributes()
QString titleText() const
bool isEmpty() const override
void setCustomTickLength(int value)
virtual bool isOrdinate() const
void setGeometry(const QRect &r) override
QSize maximumSize() const override
Q_DECL_DEPRECATED qreal titleSize() const
QList< qreal > customTicks() const
int customTickLength() const
~CartesianAxis() override
void paintCtx(PaintContext *) override
void setCachedSizeDirty() const
QSize sizeHint() const override
QSize minimumSize() const override
Qt::Orientations expandingDirections() const override
virtual bool isAbscissa() const
void setTitleTextAttributes(const TextAttributes &a)
bool compare(const CartesianAxis *other) const
virtual Position position() const
QRect geometry() const override
QMultiMap< qreal, QString > annotations() const
TextAttributes titleTextAttributes() const
void setAnnotations(const QMultiMap< qreal, QString > &annotations)
void paint(QPainter *) override
void setTitleText(const QString &text)
virtual int tickLength(bool subUnitTicks=false) const
void setCustomTicks(const QList< qreal > &ticksPostions)
bool hasDefaultTitleTextAttributes() const
Q_DECL_DEPRECATED void setTitleSpace(qreal value)
Q_DECL_DEPRECATED void setTitleSize(qreal value)
use setTitleTextAttributes() instead
virtual void layoutPlanes()
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
const GridAttributes gridAttributes(Qt::Orientation orientation) const
Helper class for one dimension of data, e.g. for the rows in a data model, or for the labels of an ax...
static QPaintDevice * paintDevice()
A set of attributes controlling the appearance of grids.
bool adjustLowerBoundToGrid() const
bool adjustUpperBoundToGrid() const
Measure is used to specify relative and absolute sizes in KDChart, e.g. font sizes.
Stores information about painting diagrams.
void setPainter(QPainter *painter)
void setCoordinatePlane(AbstractCoordinatePlane *plane)
void setRectangle(const QRectF &rect)
AbstractCoordinatePlane * coordinatePlane() const
QPainter * painter() const
A set of attributes controlling the appearance of axis rulers.
int minorTickMarkLength() const
QPen minorTickMarkPen() const
bool hasTickMarkPenAt(qreal value) const
int majorTickMarkLength() const
QPen majorTickMarkPen() const
bool showFirstTick() const
A set of text attributes.
void setFontSize(const Measure &measure)
void setRotation(int rotation)