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)