##// END OF EJS Templates
Fix axis sizehints when labels are angled...
Miikka Heikkinen -
r2412:38736d0999b4
parent child
Show More
@@ -111,31 +111,32 QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constra
111 111 qreal width=0;
112 112 qreal height=0;
113 113
114 switch (which) {
115 case Qt::MinimumSize:
116 width = fn.boundingRect("...").width();
117 height = fn.height()+labelPadding();
118 width=qMax(width,base.width());
114 switch (which) {
115 case Qt::MinimumSize: {
116 QRectF boundingRect = labelBoundingRect(fn, "...");
117 width = qMax(boundingRect.width(), base.width());
118 height = boundingRect.height() + labelPadding();
119 119 height += base.height();
120 sh = QSizeF(width,height);
120 sh = QSizeF(width, height);
121 121 break;
122 }
122 123 case Qt::PreferredSize:{
123
124 for (int i = 0; i < ticksList.size(); ++i)
125 {
126 QRectF rect = fn.boundingRect(ticksList.at(i));
124 int labelHeight = 0;
125 foreach (const QString& s, ticksList) {
126 QRect rect = labelBoundingRect(fn, s);
127 labelHeight = qMax(rect.height(), labelHeight);
127 128 width += rect.width();
128 129 }
129 height = fn.height()+labelPadding();
130 width = qMax(width,base.width());
130 height = labelHeight + labelPadding();
131 131 height += base.height();
132 sh = QSizeF(width,height);
132 width = qMax(width, base.width());
133 sh = QSizeF(width, height);
133 134 break;
134 135 }
135 136 default:
136 137 break;
137 }
138 return sh;
138 }
139 return sh;
139 140 }
140 141
141 142 #include "moc_chartbarcategoryaxisx_p.cpp"
@@ -109,27 +109,30 QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constra
109 109 qreal width=0;
110 110 qreal height=0;
111 111
112 switch (which) {
113 case Qt::MinimumSize:
114 width = fn.boundingRect("...").width() + labelPadding();
115 height = fn.height();
116 width+=base.width();
117 if(base.width()>0) width+=labelPadding();
118 height=qMax(height,base.height());
119 sh = QSizeF(width,height);
112 switch (which) {
113 case Qt::MinimumSize: {
114 QRectF boundingRect = labelBoundingRect(fn, "...");
115 width = boundingRect.width() + labelPadding();
116 width += base.width();
117 if (base.width() > 0)
118 width += labelPadding();
119 height = qMax(boundingRect.height(), base.height());
120 sh = QSizeF(width, height);
120 121 break;
122 }
121 123 case Qt::PreferredSize:{
122
123 for (int i = 0; i < ticksList.size(); ++i)
124 {
125 QRectF rect = fn.boundingRect(ticksList.at(i));
126 height+=rect.height();
127 width=qMax(rect.width()+labelPadding(),width); //one pixel torelance
124 int labelWidth = 0;
125 foreach (const QString& s, ticksList) {
126 QRect rect = labelBoundingRect(fn, s);
127 labelWidth = qMax(rect.width(), labelWidth);
128 height += rect.height();
128 129 }
129 height=qMax(height,base.height());
130 width+=base.width();
131 if(base.width()>0) width+=labelPadding();
132 sh = QSizeF(width,height);
130 width = labelWidth + labelPadding() + 1;
131 width += base.width();
132 if (base.width() > 0)
133 width += labelPadding();
134 height = qMax(height, base.height());
135 sh = QSizeF(width, height);
133 136 break;
134 137 }
135 138 default:
@@ -90,22 +90,24 QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint
90 90 qreal height = 0;
91 91
92 92 switch (which) {
93 case Qt::MinimumSize:
94 width = fn.boundingRect("...").width();
95 height = fn.height() + labelPadding();
96 width = qMax(width, base.width());
93 case Qt::MinimumSize: {
94 QRectF boundingRect = labelBoundingRect(fn, "...");
95 width = qMax(boundingRect.width(), base.width());
96 height = boundingRect.height() + labelPadding();
97 97 height += base.height();
98 98 sh = QSizeF(width, height);
99 99 break;
100 }
100 101 case Qt::PreferredSize: {
101
102 for (int i = 0; i < ticksList.size(); ++i) {
103 QRectF rect = fn.boundingRect(ticksList.at(i));
102 int labelHeight = 0;
103 foreach (const QString& s, ticksList) {
104 QRect rect = labelBoundingRect(fn, s);
105 labelHeight = qMax(rect.height(), labelHeight);
104 106 width += rect.width();
105 height = qMax(rect.height() + labelPadding(), height);
106 107 }
107 width = qMax(width, base.width());
108 height = labelHeight + labelPadding();
108 109 height += base.height();
110 width = qMax(width, base.width());
109 111 sh = QSizeF(width, height);
110 112 break;
111 113 }
@@ -90,22 +90,24 QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint
90 90 qreal height = 0;
91 91
92 92 switch (which) {
93 case Qt::MinimumSize:
94 width = fn.boundingRect("...").width() + labelPadding();
95 height = fn.height();
93 case Qt::MinimumSize: {
94 QRectF boundingRect = labelBoundingRect(fn, "...");
95 width = boundingRect.width() + labelPadding();
96 96 width += base.width();
97 height = qMax(height, base.height());;
97 height = qMax(boundingRect.height(), base.height());
98 98 sh = QSizeF(width, height);
99 99 break;
100 }
100 101 case Qt::PreferredSize: {
101
102 for (int i = 0; i < ticksList.size(); ++i) {
103 QRectF rect = fn.boundingRect(ticksList.at(i));
104 width = qMax(rect.width() + labelPadding() + 1, width);
102 int labelWidth = 0;
103 foreach (const QString& s, ticksList) {
104 QRect rect = labelBoundingRect(fn, s);
105 labelWidth = qMax(rect.width(), labelWidth);
105 106 height += rect.height();
106 107 }
107 height = qMax(height, base.height());
108 width = labelWidth + labelPadding() + 1;
108 109 width += base.width();
110 height = qMax(height, base.height());
109 111 sh = QSizeF(width, height);
110 112 break;
111 113 }
@@ -527,6 +527,20 QStringList ChartAxis::createDateTimeLabels(qreal min, qreal max,int ticks,const
527 527 return labels;
528 528 }
529 529
530 QRect ChartAxis::labelBoundingRect(const QFontMetrics &fn, const QString &label) const
531 {
532 QRect boundingRect = fn.boundingRect(label);
533
534 // Take label rotation into account
535 if (m_labelsAngle) {
536 QTransform transform;
537 transform.rotate(m_labelsAngle);
538 boundingRect = transform.mapRect(boundingRect);
539 }
540
541 return boundingRect;
542 }
543
530 544 #include "moc_chartaxis_p.cpp"
531 545
532 546 QTCOMMERCIALCHART_END_NAMESPACE
@@ -109,6 +109,7 protected:
109 109 QFont font() const;
110 110 qreal min() const;
111 111 qreal max() const;
112 QRect labelBoundingRect(const QFontMetrics &fn, const QString &label) const;
112 113
113 114 //handlers
114 115 public Q_SLOTS:
@@ -99,21 +99,24 QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint
99 99
100 100 switch (which) {
101 101 case Qt::MinimumSize:{
102 int count = qMax(ticksList.last().count(),ticksList.first().count());
103 width = fn.averageCharWidth() * count;
104 height = fn.height() + labelPadding();
105 width = qMax(width,base.width());
102 QRectF boundingRect = labelBoundingRect(fn, "...");
103 width = qMax(boundingRect.width(), base.width());
104 height = boundingRect.height() + labelPadding();
106 105 height += base.height();
107 sh = QSizeF(width,height);
106 sh = QSizeF(width, height);
108 107 break;
109 108 }
110 109 case Qt::PreferredSize: {
111 int count = qMax(ticksList.last().count(),ticksList.first().count());
112 width=fn.averageCharWidth() * count;
113 height=fn.height()+labelPadding();
114 width=qMax(width,base.width());
115 height+=base.height();
116 sh = QSizeF(width,height);
110 int labelHeight = 0;
111 foreach (const QString& s, ticksList) {
112 QRect rect = labelBoundingRect(fn, s);
113 labelHeight = qMax(rect.height(), labelHeight);
114 width += rect.width();
115 }
116 height = labelHeight + labelPadding();
117 height += base.height();
118 width = qMax(width, base.width());
119 sh = QSizeF(width, height);
117 120 break;
118 121 }
119 122 default:
@@ -99,28 +99,26 QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint
99 99 return sh;
100 100 }
101 101
102 int labelWidth = 0;
103
104 foreach(const QString& s, ticksList)
105 {
106 labelWidth=qMax(fn.width(s),labelWidth);
107 }
108
109 102 switch (which) {
110 103 case Qt::MinimumSize: {
111 width = fn.boundingRect("...").width() + labelPadding();
104 QRectF boundingRect = labelBoundingRect(fn, "...");
105 width = boundingRect.width() + labelPadding();
112 106 width += base.width();
113 height = fn.height();
114 height = qMax(height,base.height());
115 sh = QSizeF(width,height);
107 height = qMax(boundingRect.height(), base.height());
108 sh = QSizeF(width, height);
116 109 break;
117 110 }
118 111 case Qt::PreferredSize: {
112 int labelWidth = 0;
113 foreach (const QString& s, ticksList) {
114 QRect rect = labelBoundingRect(fn, s);
115 labelWidth = qMax(rect.width(), labelWidth);
116 height += rect.height();
117 }
119 118 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
120 119 width += base.width();
121 height = fn.height() * ticksList.count();
122 height = qMax(height,base.height());
123 sh = QSizeF(width,height);
120 height = qMax(height, base.height());
121 sh = QSizeF(width, height);
124 122 break;
125 123 }
126 124 default:
@@ -105,35 +105,32 void HorizontalAxis::updateGeometry()
105 105 gridItem->setLine(layout[i], gridRect.top(), layout[i], gridRect.bottom());
106 106
107 107 //label text wrapping
108 if(intervalAxis()&& i+1!=layout.size()) {
109 //wrapping in case of interval axis
110 const qreal delta = layout[i+1] - layout[i];
111 QString text = labelList.at(i);
112 if (fn.boundingRect(text).width() + 1 > delta )
113 {
114 QString label = text + "...";
115 while (fn.boundingRect(label).width() >= delta && label.length() > 3)
108 QString text = labelList.at(i);
109 QRectF boundingRect = labelBoundingRect(fn, text);
110 qreal size = axisRect.bottom() - axisRect.top() - labelPadding() - title->boundingRect().height();
111 if (boundingRect.height() > size) {
112 QString label = text + "...";
113 while (boundingRect.height() >= size && label.length() > 3) {
116 114 label.remove(label.length() - 4, 1);
117 labelItem->setText(label);
118 }
119 else {
120 labelItem->setText(text);
115 boundingRect = labelBoundingRect(fn, label);
121 116 }
122 }else{
123 labelItem->setText(labelList.at(i));
117 labelItem->setText(label);
118 } else {
119 labelItem->setText(text);
124 120 }
125 121
126 122 //label transformation origin point
127 123 const QRectF& rect = labelItem->boundingRect();
128 124 QPointF center = rect.center();
129 125 labelItem->setTransformOriginPoint(center.x(), center.y());
126 int heightDiff = rect.height() - boundingRect.height();
130 127
131 128 //ticks and label position
132 129 if (alignment() == Qt::AlignTop) {
133 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() - labelPadding());
130 labelItem->setPos(layout[i] - center.x(), axisRect.bottom() - rect.height() + (heightDiff / 2) - labelPadding());
134 131 tickItem->setLine(layout[i], axisRect.bottom(), layout[i], axisRect.bottom() - labelPadding());
135 132 } else if (alignment() == Qt::AlignBottom) {
136 labelItem->setPos(layout[i] - center.x(), axisRect.top() + labelPadding());
133 labelItem->setPos(layout[i] - center.x(), axisRect.top() - (heightDiff / 2) + labelPadding());
137 134 tickItem->setLine(layout[i], axisRect.top(), layout[i], axisRect.top() + labelPadding());
138 135 }
139 136
@@ -146,11 +143,11 void HorizontalAxis::updateGeometry()
146 143 //label overlap detection
147 144 if(labelItem->pos().x() < width ||
148 145 labelItem->pos().x() < axisRect.left() ||
149 labelItem->pos().x() + rect.width() -1 > axisRect.right()){
146 labelItem->pos().x() + boundingRect.width() -1 > axisRect.right()){
150 147 labelItem->setVisible(false);
151 148 } else {
152 149 labelItem->setVisible(true);
153 width=rect.width()+labelItem->pos().x();
150 width = boundingRect.width() + labelItem->pos().x();
154 151 }
155 152
156 153 //shades
@@ -105,21 +105,24 QSizeF ChartLogValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint
105 105
106 106 switch (which) {
107 107 case Qt::MinimumSize:{
108 int count = qMax(ticksList.last().count(),ticksList.first().count());
109 width = fn.averageCharWidth() * count;
110 height = fn.height() + labelPadding();
111 width = qMax(width,base.width());
108 QRectF boundingRect = labelBoundingRect(fn, "...");
109 width = qMax(boundingRect.width(), base.width());
110 height = boundingRect.height() + labelPadding();
112 111 height += base.height();
113 sh = QSizeF(width,height);
112 sh = QSizeF(width, height);
114 113 break;
115 114 }
116 115 case Qt::PreferredSize: {
117 int count = qMax(ticksList.last().count(),ticksList.first().count());
118 width=fn.averageCharWidth() * count;
119 height=fn.height()+labelPadding();
120 width=qMax(width,base.width());
121 height+=base.height();
122 sh = QSizeF(width,height);
116 int labelHeight = 0;
117 foreach (const QString& s, ticksList) {
118 QRect rect = labelBoundingRect(fn, s);
119 labelHeight = qMax(rect.height(), labelHeight);
120 width += rect.width();
121 }
122 height = labelHeight + labelPadding();
123 height += base.height();
124 width = qMax(width, base.width());
125 sh = QSizeF(width, height);
123 126 break;
124 127 }
125 128 default:
@@ -102,29 +102,26 QSizeF ChartLogValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint
102 102 qreal width = 0;
103 103 qreal height = 0;
104 104
105
106 int labelWidth = 0;
107
108 foreach(const QString& s, ticksList)
109 {
110 labelWidth=qMax(fn.width(s),labelWidth);
111 }
112
113 105 switch (which) {
114 106 case Qt::MinimumSize: {
115 width = fn.boundingRect("...").width() + labelPadding();
107 QRectF boundingRect = labelBoundingRect(fn, "...");
108 width = boundingRect.width() + labelPadding();
116 109 width += base.width();
117 height = fn.height();
118 height = qMax(height,base.height());
119 sh = QSizeF(width,height);
110 height = qMax(boundingRect.height(), base.height());
111 sh = QSizeF(width, height);
120 112 break;
121 113 }
122 114 case Qt::PreferredSize: {
115 int labelWidth = 0;
116 foreach (const QString& s, ticksList) {
117 QRect rect = labelBoundingRect(fn, s);
118 labelWidth = qMax(rect.width(), labelWidth);
119 height += rect.height();
120 }
123 121 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
124 122 width += base.width();
125 height = fn.height() * ticksList.count();
126 height = qMax(height,base.height());
127 sh = QSizeF(width,height);
123 height = qMax(height, base.height());
124 sh = QSizeF(width, height);
128 125 break;
129 126 }
130 127 default:
@@ -98,33 +98,29 QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
98 98
99 99 switch (which) {
100 100 case Qt::MinimumSize: {
101 if(!ticksList.empty()) {
102 foreach(QString label,ticksList) {
103 width = qMax(qreal(fn.boundingRect(label).width()),width);
104 }
105 }
106 height = fn.height() + labelPadding();
107 width = qMax(width,base.width());
101 QRectF boundingRect = labelBoundingRect(fn, "...");
102 width = qMax(boundingRect.width(), base.width());
103 height = boundingRect.height() + labelPadding();
108 104 height += base.height();
109 sh = QSizeF(width,height);
105 sh = QSizeF(width, height);
110 106 break;
111 107 }
112 108 case Qt::PreferredSize: {
113 if(!ticksList.empty()) {
114 foreach(QString label,ticksList) {
115 width+=fn.boundingRect(label).width();
116 }
109 int labelHeight = 0;
110 foreach (const QString& s, ticksList) {
111 QRect rect = labelBoundingRect(fn, s);
112 labelHeight = qMax(rect.height(), labelHeight);
113 width += rect.width();
117 114 }
118 height=fn.height()+labelPadding();
119 width=qMax(width,base.width());
120 height+=base.height();
121 sh = QSizeF(width,height);
115 height = labelHeight + labelPadding();
116 height += base.height();
117 width = qMax(width, base.width());
118 sh = QSizeF(width, height);
122 119 break;
123 120 }
124 121 default:
125 break;
122 break;
126 123 }
127
128 124 return sh;
129 125 }
130 126
@@ -95,29 +95,26 QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c
95 95 qreal width = 0;
96 96 qreal height = 0;
97 97
98 int labelWidth = 0;
99
100 foreach(const QString& s, ticksList)
101 {
102 labelWidth=qMax(fn.width(s),labelWidth);
103 }
104
105 98 switch (which) {
106 99 case Qt::MinimumSize: {
107 width = fn.boundingRect("...").width() + labelPadding();
100 QRectF boundingRect = labelBoundingRect(fn, "...");
101 width = boundingRect.width() + labelPadding();
108 102 width += base.width();
109 height = fn.height();
110 height = qMax(height,base.height());
111 sh = QSizeF(width,height);
103 height = qMax(boundingRect.height(), base.height());
104 sh = QSizeF(width, height);
112 105 break;
113 106 }
114 case Qt::PreferredSize:
115 {
107 case Qt::PreferredSize: {
108 int labelWidth = 0;
109 foreach (const QString& s, ticksList) {
110 QRect rect = labelBoundingRect(fn, s);
111 labelWidth = qMax(rect.width(), labelWidth);
112 height += rect.height();
113 }
116 114 width = labelWidth + labelPadding() + 2; //two pixels of tolerance
117 115 width += base.width();
118 height = fn.height() * ticksList.count();
119 height = qMax(height,base.height());
120 sh = QSizeF(width,height);
116 height = qMax(height, base.height());
117 sh = QSizeF(width, height);
121 118 break;
122 119 }
123 120 default:
@@ -113,27 +113,33 void VerticalAxis::updateGeometry()
113 113
114 114 //label text wrapping
115 115 QString text = labelList.at(i);
116 QRectF boundingRect = labelBoundingRect(fn, text);
117
116 118 qreal size = axisRect.right() - axisRect.left() - labelPadding() - title->boundingRect().height();
117 if (fn.boundingRect(text).width() > size) {
119 if (boundingRect.width() > size) {
118 120 QString label = text + "...";
119 while (fn.boundingRect(label).width() > size && label.length() > 3)
121 while (boundingRect.width() > size && label.length() > 3) {
120 122 label.remove(label.length() - 4, 1);
123 boundingRect = labelBoundingRect(fn, label);
124 }
121 125 labelItem->setText(label);
122 126 } else {
123 127 labelItem->setText(text);
124 128 }
129
125 130 //label transformation origin point
126 131 const QRectF &rect = labelItem->boundingRect();
127 132
128 133 QPointF center = rect.center();
129 134 labelItem->setTransformOriginPoint(center.x(), center.y());
135 int widthDiff = rect.width() - boundingRect.width();
130 136
131 137 //ticks and label position
132 138 if (alignment() == Qt::AlignLeft) {
133 labelItem->setPos(axisRect.right() - rect.width() - labelPadding() , layout[i] - center.y());
139 labelItem->setPos(axisRect.right() - rect.width() + (widthDiff / 2) - labelPadding(), layout[i] - center.y());
134 140 tickItem->setLine(axisRect.right() - labelPadding(), layout[i], axisRect.right(), layout[i]);
135 141 } else if (alignment() == Qt::AlignRight) {
136 labelItem->setPos(axisRect.left() + labelPadding() , layout[i] - center.y());
142 labelItem->setPos(axisRect.left() + labelPadding() - (widthDiff / 2), layout[i] - center.y());
137 143 tickItem->setLine(axisRect.left(), layout[i], axisRect.left() + labelPadding(), layout[i]);
138 144 }
139 145
@@ -144,9 +150,9 void VerticalAxis::updateGeometry()
144 150 }
145 151
146 152 //label overlap detection
147 if(labelItem->pos().y() + rect.height() > height ||
148 labelItem->pos().y() + rect.height()/2 > gridRect.bottom() ||
149 labelItem->pos().y() + rect.height()/2 < gridRect.top()) {
153 if(labelItem->pos().y() + boundingRect.height() > height ||
154 labelItem->pos().y() + boundingRect.height()/2 > gridRect.bottom() ||
155 labelItem->pos().y() + boundingRect.height()/2 < gridRect.top()) {
150 156 labelItem->setVisible(false);
151 157 }
152 158 else {
General Comments 0
You need to be logged in to leave comments. Login now