##// END OF EJS Templates
Add HTML support for pie slice labels...
Titta Heikkala -
r2626:ec2eee97ed6a
parent child
Show More
@@ -27,6 +27,7
27 #include <qmath.h>
27 #include <qmath.h>
28 #include <QGraphicsSceneEvent>
28 #include <QGraphicsSceneEvent>
29 #include <QTime>
29 #include <QTime>
30 #include <QTextDocument>
30 #include <QDebug>
31 #include <QDebug>
31
32
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -45,6 +46,8 PieSliceItem::PieSliceItem(QGraphicsItem *parent)
45 setAcceptHoverEvents(true);
46 setAcceptHoverEvents(true);
46 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setAcceptedMouseButtons(Qt::MouseButtonMask);
47 setZValue(ChartPresenter::PieSeriesZValue);
48 setZValue(ChartPresenter::PieSeriesZValue);
49 m_labelItem = new QGraphicsTextItem(this);
50 m_labelItem->document()->setDocumentMargin(1.0);
48 }
51 }
49
52
50 PieSliceItem::~PieSliceItem()
53 PieSliceItem::~PieSliceItem()
@@ -80,47 +83,11 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
80 painter->save();
83 painter->save();
81
84
82 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
85 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
83 // Also, the drawText actually uses the pen color for the text color (unlike QGraphicsSimpleTextItem)
84 painter->setPen(m_data.m_labelBrush.color());
85 painter->setBrush(m_data.m_labelBrush);
86 painter->setBrush(m_data.m_labelBrush);
86 painter->setFont(m_data.m_labelFont);
87
87
88 QFontMetricsF fm(m_data.m_labelFont);
88 if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
89 QString label = m_data.m_labelText;
90 QRectF labelBoundingRect;
91
92 switch (m_data.m_labelPosition) {
93 case QPieSlice::LabelOutside:
94 painter->setClipRect(parentItem()->boundingRect());
89 painter->setClipRect(parentItem()->boundingRect());
95 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
90 painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
96 if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) {
97 // Only one line label text is supported currently.
98 // The height for the label is set one pixel over the font metrics.
99 label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
100 qreal(0.0), m_labelTextRect.width(),
101 fm.height() + 1.0, labelBoundingRect);
102 }
103 painter->drawText(m_labelTextRect, Qt::AlignCenter, label);
104 break;
105 case QPieSlice::LabelInsideHorizontal:
106 painter->setClipPath(m_slicePath);
107 painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText);
108 break;
109 case QPieSlice::LabelInsideTangential:
110 painter->setClipPath(m_slicePath);
111 painter->translate(m_labelTextRect.center());
112 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2);
113 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
114 break;
115 case QPieSlice::LabelInsideNormal:
116 painter->setClipPath(m_slicePath);
117 painter->translate(m_labelTextRect.center());
118 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
119 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
120 else
121 painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
122 painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText);
123 break;
124 }
91 }
125
92
126 painter->restore();
93 painter->restore();
@@ -164,42 +131,80 void PieSliceItem::updateGeometry()
164 QPointF armStart;
131 QPointF armStart;
165 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
132 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
166
133
167 // text rect
134 if (m_data.m_isLabelVisible) {
168 QFontMetricsF fm(m_data.m_labelFont);
135 // text rect
169 m_labelTextRect = QRectF(0, 0, fm.width(m_data.m_labelText), fm.height());
136 QFontMetricsF fm(m_data.m_labelFont);
170
137 m_labelTextRect = ChartPresenter::textBoundingRect(m_data.m_labelFont,
171 // label arm path
138 m_data.m_labelText,
172 QPointF labelTextStart;
139 0);
173 m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart);
140
174
141 QString label(m_data.m_labelText);
175 // text position
142 m_labelItem->setVisible(m_data.m_isLabelVisible);
176 switch (m_data.m_labelPosition) {
143 m_labelItem->setDefaultTextColor(m_data.m_labelBrush.color());
177 case QPieSlice::LabelOutside:
144 m_labelItem->setFont(m_data.m_labelFont);
178 m_labelTextRect.moveBottomLeft(labelTextStart);
145
179 if (m_labelTextRect.left() < 0)
146 // text position
180 m_labelTextRect.setLeft(0);
147 if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
181 if (m_labelTextRect.right() > parentItem()->boundingRect().right())
148 setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
182 m_labelTextRect.setRight(parentItem()->boundingRect().right());
149
183 break;
150 // label arm path
184 case QPieSlice::LabelInsideHorizontal:
151 QPointF labelTextStart;
185 case QPieSlice::LabelInsideTangential: {
152 m_labelArmPath = labelArmPath(armStart, centerAngle,
186 QPointF textCenter;
153 m_data.m_radius * m_data.m_labelArmLengthFactor,
187 if (m_data.m_holeRadius > 0)
154 m_labelTextRect.width(), &labelTextStart);
188 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
155
189 else
156 m_labelTextRect.moveBottomLeft(labelTextStart);
190 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
157 if (m_labelTextRect.left() < 0)
191 m_labelTextRect.moveCenter(textCenter);
158 m_labelTextRect.setLeft(0);
192 break;
159 else if (m_labelTextRect.left() < parentItem()->boundingRect().left())
193 }
160 m_labelTextRect.setLeft(parentItem()->boundingRect().left());
194 case QPieSlice::LabelInsideNormal: {
161 if (m_labelTextRect.right() > parentItem()->boundingRect().right())
195 QPointF textCenter;
162 m_labelTextRect.setRight(parentItem()->boundingRect().right());
196 if (m_data.m_holeRadius > 0)
163
197 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius + (m_data.m_radius - m_data.m_holeRadius) / 2);
164 if (fm.width(m_data.m_labelText) > m_labelTextRect.width()) {
198 else
165 label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
199 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
166 qreal(0.0), m_labelTextRect.width(),
200 m_labelTextRect.moveCenter(textCenter);
167 m_labelTextRect.height(), m_labelTextRect);
201 break;
168 m_labelArmPath = labelArmPath(armStart, centerAngle,
202 }
169 m_data.m_radius * m_data.m_labelArmLengthFactor,
170 m_labelTextRect.width(), &labelTextStart);
171
172 m_labelTextRect.moveBottomLeft(labelTextStart);
173 }
174 m_labelItem->setTextWidth(m_labelTextRect.width()
175 + m_labelItem->document()->documentMargin());
176 m_labelItem->setHtml(label);
177 m_labelItem->setPos(m_labelTextRect.x(), m_labelTextRect.y() + 1.0);
178 } else {
179 // label inside
180 setFlag(QGraphicsItem::ItemClipsChildrenToShape);
181 m_labelItem->setTextWidth(m_labelTextRect.width()
182 + m_labelItem->document()->documentMargin());
183 m_labelItem->setHtml(label);
184
185 QPointF textCenter;
186 if (m_data.m_holeRadius > 0) {
187 textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius
188 + (m_data.m_radius
189 - m_data.m_holeRadius) / 2);
190 } else {
191 textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
192 }
193 m_labelItem->setPos(textCenter.x() - m_labelItem->boundingRect().width() / 2,
194 textCenter.y() - fm.height() / 2);
195
196 QPointF labelCenter = m_labelItem->boundingRect().center();
197 m_labelItem->setTransformOriginPoint(labelCenter);
198
199 if (m_data.m_labelPosition == QPieSlice::LabelInsideTangential) {
200 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2);
201 } else if (m_data.m_labelPosition == QPieSlice::LabelInsideNormal) {
202 if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
203 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
204 else
205 m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
206 }
207 }
203 }
208 }
204
209
205 // bounding rect
210 // bounding rect
@@ -81,6 +81,7 private:
81 QPainterPath m_labelArmPath;
81 QPainterPath m_labelArmPath;
82 QRectF m_labelTextRect;
82 QRectF m_labelTextRect;
83 bool m_hovered;
83 bool m_hovered;
84 QGraphicsTextItem *m_labelItem;
84
85
85 friend class PieSliceAnimation;
86 friend class PieSliceAnimation;
86 };
87 };
General Comments 0
You need to be logged in to leave comments. Login now