1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#include <QtCharts/qcategoryaxis.h>
5#include <QtCharts/QColorAxis>
6#include <QtCharts/qlogvalueaxis.h>
7#include <QtCore/qmath.h>
8#include <private/chartpresenter_p.h>
9#include <private/verticalaxis_p.h>
10#include <private/qabstractaxis_p.h>
11
12QT_BEGIN_NAMESPACE
13
14VerticalAxis::VerticalAxis(QAbstractAxis *axis, QGraphicsItem *item, bool intervalAxis)
15 : CartesianChartAxis(axis, item, intervalAxis)
16{
17}
18
19VerticalAxis::~VerticalAxis()
20{
21}
22
23QSizeF VerticalAxis::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
24{
25 Q_UNUSED(constraint);
26 QSizeF sh(0, 0);
27
28 if (axis()->titleText().isEmpty() || !titleItem()->isVisible())
29 return sh;
30
31 switch (which) {
32 case Qt::MinimumSize: {
33 QRectF titleRect = ChartPresenter::textBoundingRect(font: axis()->titleFont(),
34 QStringLiteral("..."));
35 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
36 break;
37 }
38 case Qt::MaximumSize:
39 case Qt::PreferredSize: {
40 QRectF titleRect = ChartPresenter::textBoundingRect(font: axis()->titleFont(), text: axis()->titleText());
41 sh = QSizeF(titleRect.height() + (titlePadding() * 2.0), titleRect.width());
42 break;
43 }
44 default:
45 break;
46 }
47 return sh;
48}
49
50void VerticalAxis::updateGeometry()
51{
52 const QList<qreal> &layout = ChartAxisElement::layout();
53 const QList<qreal> &dynamicMinorTicklayout = ChartAxisElement::dynamicMinorTicklayout();
54
55 if (layout.isEmpty() && dynamicMinorTicklayout.isEmpty()
56 && axis()->type() != QAbstractAxis::AxisTypeLogValue) {
57 return;
58 }
59
60 QStringList labelList = labels();
61
62 QList<QGraphicsItem *> labels = labelItems();
63 QList<QGraphicsItem *> arrow = arrowItems();
64 QGraphicsTextItem *title = titleItem();
65
66 Q_ASSERT(labels.size() == labelList.size());
67 Q_ASSERT(layout.size() == labelList.size());
68
69 const QRectF &axisRect = axisGeometry();
70 const QRectF &gridRect = gridGeometry();
71
72 qreal height = axisRect.bottom();
73
74 //arrow
75 QGraphicsLineItem *arrowItem = static_cast<QGraphicsLineItem*>(arrow.at(i: 0));
76
77 //arrow position
78 if (axis()->type() != QAbstractAxis::AxisTypeColor) {
79 if (axis()->alignment() == Qt::AlignLeft)
80 arrowItem->setLine(x1: axisRect.right(), y1: gridRect.top(), x2: axisRect.right(), y2: gridRect.bottom());
81 else if (axis()->alignment() == Qt::AlignRight)
82 arrowItem->setLine(x1: axisRect.left(), y1: gridRect.top(), x2: axisRect.left(), y2: gridRect.bottom());
83 }
84
85 //title
86 QRectF titleBoundingRect;
87 QString titleText = axis()->titleText();
88 qreal labelAvailableSpace = axisRect.width();
89 if (!titleText.isEmpty() && titleItem()->isVisible()) {
90 const qreal titleAvailableSpace =
91 axisRect.width() - labelPadding() - (titlePadding() * 2.0);
92 qreal minimumLabelWidth = ChartPresenter::textBoundingRect(font: axis()->labelsFont(),
93 QStringLiteral("...")).width();
94 qreal titleSpace = titleAvailableSpace - minimumLabelWidth;
95
96 if (axis()->type() == QAbstractAxis::AxisTypeColor) {
97 QColorAxis *colorAxis = static_cast<QColorAxis *>(axis());
98 titleSpace -= colorAxis->size() + colorScalePadding();
99 }
100
101 title->setHtml(ChartPresenter::truncatedText(font: axis()->titleFont(), text: titleText, angle: qreal(90.0),
102 maxWidth: titleSpace, maxHeight: gridRect.height(),
103 boundingRect&: titleBoundingRect));
104
105 title->setTextWidth(titleBoundingRect.height());
106
107 titleBoundingRect = title->boundingRect();
108
109 QPointF center = gridRect.center() - titleBoundingRect.center();
110 if (axis()->alignment() == Qt::AlignLeft) {
111 title->setPos(ax: axisRect.left() - titleBoundingRect.width() / 2.0
112 + titleBoundingRect.height() / 2.0 + titlePadding(), ay: center.y());
113 } else if (axis()->alignment() == Qt::AlignRight) {
114 title->setPos(ax: axisRect.right() - titleBoundingRect.width() / 2.0
115 - titleBoundingRect.height() / 2.0 - titlePadding(), ay: center.y());
116 }
117
118 title->setTransformOriginPoint(titleBoundingRect.center());
119 title->setRotation(270);
120 labelAvailableSpace -= titleBoundingRect.height();
121
122 if (axis()->type() == QAbstractAxis::AxisTypeColor) {
123 QColorAxis *colorAxis = static_cast<QColorAxis *>(axis());
124 labelAvailableSpace -= colorAxis->size() + colorScalePadding();
125 }
126 }
127
128 QList<QGraphicsItem *> lines = gridItems();
129 QList<QGraphicsItem *> shades = shadeItems();
130
131 bool labelsTruncated = false;
132
133 for (int i = 0; i < layout.size(); ++i) {
134 //items
135 QGraphicsLineItem *gridItem = static_cast<QGraphicsLineItem *>(lines.at(i));
136 QGraphicsLineItem *tickItem = static_cast<QGraphicsLineItem *>(arrow.at(i: i + 1));
137 QGraphicsTextItem *labelItem = static_cast<QGraphicsTextItem *>(labels.at(i));
138
139 //grid line
140 if (axis()->isReverse()) {
141 gridItem->setLine(x1: gridRect.left(), y1: gridRect.top() + gridRect.bottom() - layout[i],
142 x2: gridRect.right(), y2: gridRect.top() + gridRect.bottom() - layout[i]);
143 } else {
144 gridItem->setLine(x1: gridRect.left(), y1: layout[i], x2: gridRect.right(), y2: layout[i]);
145 }
146
147 //label text wrapping
148 QString text;
149 if (axis()->isReverse() && axis()->type() != QAbstractAxis::AxisTypeCategory)
150 text = labelList.at(i: labelList.size() - i - 1);
151 else
152 text = labelList.at(i);
153
154 QRectF boundingRect;
155 // don't truncate empty labels
156 if (text.isEmpty()) {
157 labelItem->setHtml(text);
158 } else {
159 QString displayText = text;
160 if (axis()->truncateLabels()) {
161 qreal labelHeight = (axisRect.height() / layout.size()) - (2 * labelPadding());
162 // Replace digits with ellipsis "..." if number does not fit
163 displayText =
164 ChartPresenter::truncatedText(font: axis()->labelsFont(), text, angle: axis()->labelsAngle(),
165 maxWidth: labelAvailableSpace, maxHeight: labelHeight, boundingRect);
166 } else {
167 boundingRect = ChartPresenter::textBoundingRect(font: axis()->labelsFont(),
168 text: displayText, angle: axis()->labelsAngle());
169 }
170
171 labelItem->setTextWidth(ChartPresenter::textBoundingRect(font: axis()->labelsFont(),
172 text: displayText).width());
173
174 labelItem->setHtml(displayText);
175
176 labelsTruncated |= displayText != text;
177 }
178
179 //label transformation origin point
180 const QRectF &rect = labelItem->boundingRect();
181 QPointF center = rect.center();
182 labelItem->setTransformOriginPoint(ax: center.x(), ay: center.y());
183 qreal widthDiff = rect.width() - boundingRect.width();
184 qreal heightDiff = rect.height() - boundingRect.height();
185
186 //ticks and label position
187 QPointF labelPos;
188 if (axis()->alignment() == Qt::AlignLeft) {
189
190 qreal tickStopX = axisRect.right();
191
192 if (axis()->type() == QAbstractAxis::AxisTypeColor) {
193 QColorAxis *colorAxis = static_cast<QColorAxis *>(axis());
194 QGraphicsPixmapItem *colorScale = colorScaleItem();
195
196 const qreal penWidth = axis()->linePen().widthF();
197 // penWidth / 2 is half of tick width
198 colorScale->setOffset(ax: axisRect.right() - colorAxis->size() - colorScalePadding(),
199 ay: layout[i] - penWidth / 2);
200 prepareColorScale(width: colorAxis->size(), height: gridRect.height() + penWidth);
201
202 tickStopX = axisRect.right() - colorAxis->size() - colorScalePadding();
203 }
204
205 if (axis()->isReverse()) {
206 labelPos = QPointF(tickStopX - rect.width() + (widthDiff / 2.0) - labelPadding(),
207 gridRect.top() + gridRect.bottom()
208 - layout[layout.size() - i - 1] - center.y());
209 tickItem->setLine(x1: tickStopX - labelPadding(),
210 y1: gridRect.top() + gridRect.bottom() - layout[i], x2: tickStopX,
211 y2: gridRect.top() + gridRect.bottom() - layout[i]);
212 } else {
213 labelPos = QPointF(tickStopX - rect.width() + (widthDiff / 2.0) - labelPadding(),
214 layout[i] - center.y());
215 tickItem->setLine(x1: tickStopX - labelPadding(), y1: layout[i], x2: tickStopX, y2: layout[i]);
216 }
217 } else if (axis()->alignment() == Qt::AlignRight) {
218 qreal tickStartX = axisRect.left();
219
220 if (axis()->type() == QAbstractAxis::AxisTypeColor) {
221 QColorAxis *colorAxis = static_cast<QColorAxis *>(axis());
222 QGraphicsPixmapItem *colorScale = colorScaleItem();
223
224 const qreal penWidth = axis()->linePen().widthF();
225 // penWidth / 2 is half of tick width
226 colorScale->setOffset(ax: axisRect.x() + colorScalePadding(), ay: layout[i] - penWidth / 2);
227 prepareColorScale(width: colorAxis->size(), height: gridRect.height() + penWidth);
228
229 tickStartX = axisRect.x() + colorScalePadding() + colorAxis->size();
230 }
231
232
233 if (axis()->isReverse()) {
234 tickItem->setLine(x1: tickStartX, y1: gridRect.top() + gridRect.bottom() - layout[i],
235 x2: tickStartX + labelPadding(),
236 y2: gridRect.top() + gridRect.bottom() - layout[i]);
237 labelPos = QPointF(tickStartX + labelPadding() - (widthDiff / 2.0),
238 gridRect.top() + gridRect.bottom()
239 - layout[layout.size() - i - 1] - center.y());
240 } else {
241
242 labelPos = QPointF(tickStartX + labelPadding() - (widthDiff / 2.0),
243 layout[i] - center.y());
244 tickItem->setLine(x1: tickStartX, y1: layout[i], x2: tickStartX + labelPadding(), y2: layout[i]);
245 }
246 }
247
248 //label in between
249 bool forceHide = false;
250 bool labelOnValue = false;
251 if (intervalAxis() && (i + 1) != layout.size()
252 && axis()->type() != QAbstractAxis::AxisTypeColor) {
253 qreal lowerBound;
254 qreal upperBound;
255 if (axis()->isReverse()) {
256 lowerBound = qMax(a: gridRect.top() + gridRect.bottom() - layout[i + 1],
257 b: gridRect.top());
258 upperBound = qMin(a: gridRect.top() + gridRect.bottom() - layout[i],
259 b: gridRect.bottom());
260 } else {
261 lowerBound = qMin(a: layout[i], b: gridRect.bottom());
262 upperBound = qMax(a: layout[i + 1], b: gridRect.top());
263 }
264 const qreal delta = lowerBound - upperBound;
265 if (axis()->type() != QAbstractAxis::AxisTypeCategory) {
266 // Hide label in case visible part of the category at the grid edge is too narrow
267 if (delta < boundingRect.height()
268 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
269 forceHide = true;
270 } else {
271 labelPos.setY(lowerBound - (delta / 2.0) - center.y());
272 }
273 } else {
274 QCategoryAxis *categoryAxis = static_cast<QCategoryAxis *>(axis());
275 if (categoryAxis->labelsPosition() == QCategoryAxis::AxisLabelsPositionCenter) {
276 if (delta < boundingRect.height()
277 && (lowerBound == gridRect.bottom() || upperBound == gridRect.top())) {
278 forceHide = true;
279 } else {
280 labelPos.setY(lowerBound - (delta / 2.0) - center.y());
281 }
282 } else if (categoryAxis->labelsPosition()
283 == QCategoryAxis::AxisLabelsPositionOnValue) {
284 labelOnValue = true;
285 if (axis()->isReverse()) {
286 labelPos.setY(gridRect.top() + gridRect.bottom()
287 - layout[i + 1] - center.y());
288 } else {
289 labelPos.setY(upperBound - center.y());
290 }
291 }
292 }
293 }
294
295 // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
296 labelItem->setPos(labelPos.toPoint());
297
298 //label overlap detection - compensate one pixel for rounding errors
299 if (axis()->isReverse()) {
300 if (forceHide)
301 labelItem->setVisible(false);
302 } else if (labelItem->pos().y() + boundingRect.height() > height || forceHide ||
303 ((labelItem->pos().y() + (heightDiff / 2.0) - 1.0) > axisRect.bottom()
304 && !labelOnValue) ||
305 (labelItem->pos().y() + (heightDiff / 2.0) < (axisRect.top() - 1.0) && !labelOnValue)) {
306 labelItem->setVisible(false);
307 }
308 else {
309 labelItem->setVisible(true);
310 height=labelItem->pos().y();
311 }
312
313 //shades
314 QGraphicsRectItem *shadeItem = 0;
315 if (i == 0)
316 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(i: 0));
317 else if (i % 2)
318 shadeItem = static_cast<QGraphicsRectItem *>(shades.at(i: (i / 2) + 1));
319 if (shadeItem) {
320 qreal lowerBound;
321 qreal upperBound;
322 if (i == 0) {
323 if (axis()->isReverse()) {
324 upperBound = gridRect.top();
325 lowerBound = gridRect.top() + gridRect.bottom() - layout[i];
326 } else {
327 lowerBound = gridRect.bottom();
328 upperBound = layout[0];
329 }
330 } else {
331 if (axis()->isReverse()) {
332 upperBound = gridRect.top() + gridRect.bottom() - layout[i];
333 if (i == layout.size() - 1) {
334 lowerBound = gridRect.bottom();
335 } else {
336 lowerBound = qMax(a: gridRect.top() + gridRect.bottom() - layout[i + 1],
337 b: gridRect.top());
338 }
339 } else {
340 lowerBound = layout[i];
341 if (i == layout.size() - 1)
342 upperBound = gridRect.top();
343 else
344 upperBound = qMax(a: layout[i + 1], b: gridRect.top());
345 }
346
347 }
348 if (lowerBound > gridRect.bottom())
349 lowerBound = gridRect.bottom();
350 if (upperBound < gridRect.top())
351 upperBound = gridRect.top();
352 shadeItem->setRect(ax: gridRect.left(), ay: upperBound, w: gridRect.width(),
353 h: lowerBound - upperBound);
354 if (shadeItem->rect().height() <= 0.0)
355 shadeItem->setVisible(false);
356 else
357 shadeItem->setVisible(true);
358 }
359
360 // check if the grid line and the axis tick should be shown
361 const bool gridLineVisible = (gridItem->line().p1().y() >= gridRect.top()
362 && gridItem->line().p1().y() <= gridRect.bottom());
363 gridItem->setVisible(gridLineVisible);
364 tickItem->setVisible(gridLineVisible);
365 }
366
367 axis()->d_ptr->setLabelsTruncated(labelsTruncated);
368
369 updateMinorTickGeometry();
370
371 // begin/end grid line in case labels between
372 if (intervalAxis()) {
373 QGraphicsLineItem *gridLine;
374 gridLine = static_cast<QGraphicsLineItem *>(lines.at(i: layout.size()));
375 gridLine->setLine(x1: gridRect.left(), y1: gridRect.top(), x2: gridRect.right(), y2: gridRect.top());
376 gridLine->setVisible(true);
377 gridLine = static_cast<QGraphicsLineItem*>(lines.at(i: layout.size() + 1));
378 gridLine->setLine(x1: gridRect.left(), y1: gridRect.bottom(), x2: gridRect.right(), y2: gridRect.bottom());
379 gridLine->setVisible(true);
380 }
381}
382
383void VerticalAxis::updateMinorTickGeometry()
384{
385 if (!axis())
386 return;
387
388 QList<qreal> layout = ChartAxisElement::layout();
389 int minorTickCount = 0;
390 qreal tickSpacing = 0.0;
391 QList<qreal> minorTickSpacings;
392 switch (axis()->type()) {
393 case QAbstractAxis::AxisTypeValue: {
394 const QValueAxis *valueAxis = qobject_cast<QValueAxis *>(object: axis());
395
396 minorTickCount = valueAxis->minorTickCount();
397
398 if (valueAxis->tickType() == QValueAxis::TicksFixed) {
399 if (valueAxis->tickCount() >= 2)
400 tickSpacing = layout.at(i: 0) - layout.at(i: 1);
401
402 for (int i = 0; i < minorTickCount; ++i) {
403 const qreal ratio = (1.0 / qreal(minorTickCount + 1)) * qreal(i + 1);
404 minorTickSpacings.append(t: tickSpacing * ratio);
405 }
406 }
407 break;
408 }
409 case QAbstractAxis::AxisTypeLogValue: {
410 const QLogValueAxis *logValueAxis = qobject_cast<QLogValueAxis *>(object: axis());
411 const qreal base = logValueAxis->base();
412 const qreal logBase = qLn(v: base);
413
414 minorTickCount = logValueAxis->minorTickCount();
415 if (minorTickCount < 0)
416 minorTickCount = qMax(a: qFloor(v: base) - 2, b: 0);
417
418 // Two "virtual" ticks are required to make sure that all minor ticks
419 // are displayed properly (even for the partially visible segments of
420 // the chart).
421 if (layout.size() >= 2) {
422 // Calculate tickSpacing as a difference between visible ticks
423 // whenever it is possible. Virtual ticks will not be correctly
424 // positioned when the layout is animating.
425 tickSpacing = layout.at(i: 0) - layout.at(i: 1);
426 layout.prepend(t: layout.at(i: 0) + tickSpacing);
427 layout.append(t: layout.at(i: layout.size() - 1) - tickSpacing);
428 } else {
429 const qreal logMax = qLn(v: logValueAxis->max()) / logBase;
430 const qreal logMin = qLn(v: logValueAxis->min()) / logBase;
431 const qreal logExtraMaxTick = qFloor(v: logMax) + 1.0;
432 const qreal logExtraMinTick = qCeil(v: logMin) - 1.0;
433 const qreal edge = gridGeometry().bottom();
434 const qreal delta = gridGeometry().height() / qAbs(t: logMax - logMin);
435 const qreal extraMaxTick = edge - (logExtraMaxTick - qMin(a: logMin, b: logMax)) * delta;
436 const qreal extraMinTick = edge - (logExtraMinTick - qMin(a: logMin, b: logMax)) * delta;
437
438 // Calculate tickSpacing using one (if layout.size() == 1) or two
439 // (if layout.size() == 0) "virtual" ticks. In both cases animation
440 // will not work as expected. This should be fixed later.
441 layout.prepend(t: extraMinTick);
442 layout.append(t: extraMaxTick);
443 tickSpacing = layout.at(i: 0) - layout.at(i: 1);
444 }
445
446 const qreal minorTickStepValue = qFabs(v: base - 1.0) / qreal(minorTickCount + 1);
447 for (int i = 0; i < minorTickCount; ++i) {
448 const qreal x = minorTickStepValue * qreal(i + 1) + 1.0;
449 const qreal minorTickSpacing = tickSpacing * (qLn(v: x) / logBase);
450 minorTickSpacings.append(t: minorTickSpacing);
451 }
452 break;
453 }
454 default:
455 // minor ticks are not supported
456 break;
457 }
458
459 const QValueAxis *valueAxis = qobject_cast<QValueAxis *>(object: axis());
460 if (valueAxis && valueAxis->tickType() == QValueAxis::TicksDynamic) {
461 const QList<qreal> dynamicMinorTicklayout = ChartAxisElement::dynamicMinorTicklayout();
462 const QRectF &gridRect = gridGeometry();
463 const qreal deltaY = gridRect.height() / (valueAxis->max() - valueAxis->min());
464 const qreal bottomPos = gridRect.bottom();
465 const qreal topPos = gridRect.top();
466
467 for (int i = 0; i < dynamicMinorTicklayout.size(); i++) {
468 QGraphicsLineItem *minorGridLineItem =
469 static_cast<QGraphicsLineItem *>(minorGridItems().value(i));
470 QGraphicsLineItem *minorArrowLineItem =
471 static_cast<QGraphicsLineItem *>(minorArrowItems().value(i));
472 if (!minorGridLineItem || !minorArrowLineItem)
473 continue;
474
475 qreal minorGridLineItemY = 0.0;
476 if (axis()->isReverse())
477 minorGridLineItemY = topPos + dynamicMinorTicklayout.at(i) * deltaY;
478 else
479 minorGridLineItemY = bottomPos - dynamicMinorTicklayout.at(i) * deltaY;
480
481 qreal minorArrowLineItemX1;
482 qreal minorArrowLineItemX2;
483 switch (axis()->alignment()) {
484 case Qt::AlignLeft:
485 minorArrowLineItemX1 = gridGeometry().left() - labelPadding() / 2.0;
486 minorArrowLineItemX2 = gridGeometry().left();
487 break;
488 case Qt::AlignRight:
489 minorArrowLineItemX1 = gridGeometry().right();
490 minorArrowLineItemX2 = gridGeometry().right() + labelPadding() / 2.0;
491 break;
492 default:
493 minorArrowLineItemX1 = 0.0;
494 minorArrowLineItemX2 = 0.0;
495 break;
496 }
497
498 minorGridLineItem->setLine(x1: gridGeometry().left(), y1: minorGridLineItemY,
499 x2: gridGeometry().right(), y2: minorGridLineItemY);
500 minorArrowLineItem->setLine(x1: minorArrowLineItemX1, y1: minorGridLineItemY,
501 x2: minorArrowLineItemX2, y2: minorGridLineItemY);
502
503 // check if the minor grid line and the minor axis arrow should be shown
504 bool minorGridLineVisible = (minorGridLineItemY >= gridGeometry().top()
505 && minorGridLineItemY <= gridGeometry().bottom());
506 minorGridLineItem->setVisible(minorGridLineVisible);
507 minorArrowLineItem->setVisible(minorGridLineVisible);
508 }
509 } else {
510 if (minorTickCount < 1 || tickSpacing == 0.0 || minorTickSpacings.size() != minorTickCount)
511 return;
512
513 for (int i = 0; i < layout.size() - 1; ++i) {
514 for (int j = 0; j < minorTickCount; ++j) {
515 const int minorItemIndex = i * minorTickCount + j;
516 QGraphicsLineItem *minorGridLineItem =
517 static_cast<QGraphicsLineItem *>(minorGridItems().value(i: minorItemIndex));
518 QGraphicsLineItem *minorArrowLineItem =
519 static_cast<QGraphicsLineItem *>(minorArrowItems().value(i: minorItemIndex));
520 if (!minorGridLineItem || !minorArrowLineItem)
521 continue;
522
523 const qreal minorTickSpacing = minorTickSpacings.value(i: j, defaultValue: 0.0);
524
525 qreal minorGridLineItemY = 0.0;
526 if (axis()->isReverse()) {
527 minorGridLineItemY = std::floor(x: gridGeometry().top() + gridGeometry().bottom()
528 - layout.at(i) + minorTickSpacing);
529 } else {
530 minorGridLineItemY = std::ceil(x: layout.at(i) - minorTickSpacing);
531 }
532
533 qreal minorArrowLineItemX1;
534 qreal minorArrowLineItemX2;
535 switch (axis()->alignment()) {
536 case Qt::AlignLeft:
537 minorArrowLineItemX1 = gridGeometry().left() - labelPadding() / 2.0;
538 minorArrowLineItemX2 = gridGeometry().left();
539 break;
540 case Qt::AlignRight:
541 minorArrowLineItemX1 = gridGeometry().right();
542 minorArrowLineItemX2 = gridGeometry().right() + labelPadding() / 2.0;
543 break;
544 default:
545 minorArrowLineItemX1 = 0.0;
546 minorArrowLineItemX2 = 0.0;
547 break;
548 }
549
550 minorGridLineItem->setLine(x1: gridGeometry().left(), y1: minorGridLineItemY,
551 x2: gridGeometry().right(), y2: minorGridLineItemY);
552 minorArrowLineItem->setLine(x1: minorArrowLineItemX1, y1: minorGridLineItemY,
553 x2: minorArrowLineItemX2, y2: minorGridLineItemY);
554
555 // check if the minor grid line and the minor axis arrow should be shown
556 bool minorGridLineVisible = (minorGridLineItemY >= gridGeometry().top()
557 && minorGridLineItemY <= gridGeometry().bottom());
558 minorGridLineItem->setVisible(minorGridLineVisible);
559 minorArrowLineItem->setVisible(minorGridLineVisible);
560 }
561 }
562 }
563}
564
565QT_END_NAMESPACE
566

source code of qtcharts/src/charts/axis/verticalaxis.cpp