1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #include <private/chartcategoryaxisx_p.h> |
5 | #include <QtCharts/QCategoryAxis> |
6 | #include <QtCharts/QAbstractAxis> |
7 | #include <private/chartpresenter_p.h> |
8 | #include <private/abstractchartlayout_p.h> |
9 | #include <QtWidgets/QGraphicsLayout> |
10 | #include <QtCore/QtMath> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | ChartCategoryAxisX::ChartCategoryAxisX(QCategoryAxis *axis, QGraphicsItem* item) |
15 | : HorizontalAxis(axis, item, true), |
16 | m_axis(axis) |
17 | { |
18 | QObject::connect(sender: axis, SIGNAL(categoriesChanged()), receiver: this, SLOT(handleCategoriesChanged())); |
19 | } |
20 | |
21 | ChartCategoryAxisX::~ChartCategoryAxisX() |
22 | { |
23 | } |
24 | |
25 | QList<qreal> ChartCategoryAxisX::calculateLayout() const |
26 | { |
27 | int tickCount = m_axis->categoriesLabels().size() + 1; |
28 | QList<qreal> points; |
29 | |
30 | if (tickCount < 2) |
31 | return points; |
32 | |
33 | const QRectF &gridRect = gridGeometry(); |
34 | qreal range = max() - min(); |
35 | if (range > 0) { |
36 | points.resize(size: tickCount); |
37 | qreal scale = gridRect.width() / range; |
38 | for (int i = 0; i < tickCount; ++i) { |
39 | if (i < tickCount - 1) { |
40 | qreal x = (m_axis->startValue(categoryLabel: m_axis->categoriesLabels().at(i)) - min()) * scale + gridRect.left(); |
41 | points[i] = x; |
42 | } else { |
43 | qreal x = (m_axis->endValue(categoryLabel: m_axis->categoriesLabels().at(i: i - 1)) - min()) * scale + gridRect.left(); |
44 | points[i] = x; |
45 | } |
46 | } |
47 | } |
48 | |
49 | return points; |
50 | } |
51 | |
52 | void ChartCategoryAxisX::updateGeometry() |
53 | { |
54 | setLabels(m_axis->categoriesLabels() << QString()); |
55 | HorizontalAxis::updateGeometry(); |
56 | } |
57 | |
58 | QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const |
59 | { |
60 | Q_UNUSED(constraint); |
61 | |
62 | QSizeF sh; |
63 | QSizeF base = HorizontalAxis::sizeHint(which, constraint); |
64 | QStringList ticksList = m_axis->categoriesLabels(); |
65 | qreal width = 0; // Width is irrelevant for X axes with interval labels |
66 | qreal height = 0; |
67 | |
68 | switch (which) { |
69 | case Qt::MinimumSize: { |
70 | if (labelsVisible()) { |
71 | QRectF boundingRect = ChartPresenter::textBoundingRect(font: axis()->labelsFont(), |
72 | QStringLiteral("..." ), |
73 | angle: axis()->labelsAngle()); |
74 | height = boundingRect.height() + labelPadding() + base.height() + 1.0; |
75 | } else { |
76 | height = base.height() + 1.0; |
77 | } |
78 | sh = QSizeF(width, height); |
79 | break; |
80 | } |
81 | case Qt::PreferredSize: { |
82 | if (labelsVisible()) { |
83 | qreal labelHeight = 0.0; |
84 | foreach (const QString& s, ticksList) { |
85 | QRectF rect = ChartPresenter::textBoundingRect(font: axis()->labelsFont(), text: s, angle: axis()->labelsAngle()); |
86 | labelHeight = qMax(a: rect.height(), b: labelHeight); |
87 | } |
88 | height = labelHeight + labelPadding() + base.height() + 1.0; |
89 | } else { |
90 | height = base.height() + 1.0; |
91 | } |
92 | sh = QSizeF(width, height); |
93 | break; |
94 | } |
95 | default: |
96 | break; |
97 | } |
98 | |
99 | return sh; |
100 | } |
101 | |
102 | void ChartCategoryAxisX::handleCategoriesChanged() |
103 | { |
104 | QGraphicsLayoutItem::updateGeometry(); |
105 | presenter()->layout()->invalidate(); |
106 | } |
107 | |
108 | QT_END_NAMESPACE |
109 | |
110 | #include "moc_chartcategoryaxisx_p.cpp" |
111 | |