##// END OF EJS Templates
Fix legend truncation...
Titta Heikkala -
r2617:57e2d8f758e8
parent child
Show More
@@ -136,19 +136,97 void LegendLayout::setAttachedGeometry(const QRectF &rect)
136 switch(m_legend->alignment()) {
136 switch(m_legend->alignment()) {
137 case Qt::AlignTop:
137 case Qt::AlignTop:
138 case Qt::AlignBottom: {
138 case Qt::AlignBottom: {
139 // Calculate the space required for items and add them to a sorted list.
140 qreal markerItemsWidth = 0;
141 qreal itemMargins = 0;
142 QList<LegendWidthStruct *> legendWidthList;
143 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
144 LegendMarkerItem *item = marker->d_ptr->item();
145 if (item->isVisible()) {
146 QSizeF dummySize;
147 qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width();
148 LegendWidthStruct *structItem = new LegendWidthStruct;
149 structItem->item = item;
150 structItem->width = itemWidth;
151 legendWidthList.append(structItem);
152 markerItemsWidth += itemWidth;
153 itemMargins += marker->d_ptr->item()->m_margin;
154 }
155 }
156 qSort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan);
157
158 // If the items would occupy more space than is available, start truncating them
159 // from the longest one.
160 qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins;
161 if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 1) {
162 bool truncated(false);
163 int count = legendWidthList.count();
164 for (int i = 1; i < count; i++) {
165 int truncateIndex = i - 1;
166
167 while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width
168 && !truncated) {
169 legendWidthList.at(truncateIndex)->width--;
170 markerItemsWidth--;
171 if (i > 1) {
172 // Truncate the items that are before the truncated one in the list.
173 for (int j = truncateIndex - 1; j >= 0; j--) {
174 if (legendWidthList.at(truncateIndex)->width
175 < legendWidthList.at(j)->width) {
176 legendWidthList.at(j)->width--;
177 markerItemsWidth--;
178 }
179 }
180 }
181 if (markerItemsWidth < availableGeometry)
182 truncated = true;
183 }
184 // Truncate the last item if needed.
185 if (i == count - 1) {
186 if (legendWidthList.at(count - 1)->width
187 > legendWidthList.at(truncateIndex)->width) {
188 legendWidthList.at(count - 1)->width--;
189 markerItemsWidth--;
190 }
191 }
192
193 if (truncated)
194 break;
195 }
196 // Items are of same width and all of them need to be truncated.
197 while (markerItemsWidth >= availableGeometry) {
198 for (int i = 0; i < count; i++) {
199 legendWidthList.at(i)->width--;
200 markerItemsWidth--;
201 }
202 }
203 }
204
139 QPointF point(0,0);
205 QPointF point(0,0);
140 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
206 foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
141 LegendMarkerItem *item = marker->d_ptr->item();
207 LegendMarkerItem *item = marker->d_ptr->item();
142 if (item->isVisible()) {
208 if (item->isVisible()) {
143 item->setGeometry(geometry);
209 QRectF itemRect = geometry;
210 qreal availableWidth = 0;
211 for (int i = 0; i < legendWidthList.size(); ++i) {
212 if (legendWidthList.at(i)->item == item) {
213 availableWidth = legendWidthList.at(i)->width;
214 break;
215 }
216 }
217 itemRect.setWidth(availableWidth);
218 item->setGeometry(itemRect);
144 item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
219 item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
145 const QRectF &rect = item->boundingRect();
220 const QRectF &rect = item->boundingRect();
146 size = size.expandedTo(rect.size());
221 size = size.expandedTo(rect.size());
147 qreal w = rect.width();
222 qreal w = rect.width();
148 m_width+=w;
223 m_width = m_width + w - item->m_margin;
149 point.setX(point.x() + w);
224 point.setX(point.x() + w);
150 }
225 }
151 }
226 }
227 // Delete structs from the container
228 qDeleteAll(legendWidthList);
229
152 if (m_width < geometry.width())
230 if (m_width < geometry.width())
153 m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
231 m_legend->d_ptr->items()->setPos(geometry.width() / 2 - m_width / 2, geometry.top());
154 else
232 else
@@ -405,4 +483,10 QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) cons
405 return size;
483 return size;
406 }
484 }
407
485
486 bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1,
487 const LegendWidthStruct *item2)
488 {
489 return item1->width > item2->width;
490 }
491
408 QTCOMMERCIALCHART_END_NAMESPACE
492 QTCOMMERCIALCHART_END_NAMESPACE
@@ -35,6 +35,7
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class QLegend;
37 class QLegend;
38 class LegendMarkerItem;
38
39
39 class LegendLayout : public QGraphicsLayout
40 class LegendLayout : public QGraphicsLayout
40 {
41 {
@@ -59,6 +60,13 private:
59 void setAttachedGeometry(const QRectF &rect);
60 void setAttachedGeometry(const QRectF &rect);
60 void setDettachedGeometry(const QRectF &rect);
61 void setDettachedGeometry(const QRectF &rect);
61
62
63 struct LegendWidthStruct {
64 LegendMarkerItem *item;
65 qreal width;
66 };
67 static bool widthLongerThan(const LegendWidthStruct *item1,
68 const LegendWidthStruct *item2);
69
62 private:
70 private:
63 QLegend *m_legend;
71 QLegend *m_legend;
64 qreal m_offsetX;
72 qreal m_offsetX;
General Comments 0
You need to be logged in to leave comments. Login now