##// END OF EJS Templates
Fix pie slice label visibility...
Fix pie slice label visibility Hide the pie slice label if it's not inside the bounding rectangle of the parent item. Task-number: QTRD-2530 Change-Id: Ifa09f7ee9e35c301f3abfd3ddab1ac3a4545af3e Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>

File last commit:

r2655:5086492877e0
r2655:5086492877e0
Show More
piesliceitem.cpp
313 lines | 11.1 KiB | text/x-c | CppLexer
Jani Honkonen
Add license headers
r794 /****************************************************************************
**
Miikka Heikkinen
Fixed the copyright year 2012 -> 2013
r2432 ** Copyright (C) 2013 Digia Plc
Jani Honkonen
Add license headers
r794 ** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
Miikka Heikkinen
Qt Commercial -> Qt Enterprise...
r2574 ** This file is part of the Qt Enterprise Charts Add-on.
Jani Honkonen
Add license headers
r794 **
** $QT_BEGIN_LICENSE$
Miikka Heikkinen
Qt Commercial -> Qt Enterprise...
r2574 ** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
Jani Honkonen
Add license headers
r794 ** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
** $QT_END_LICENSE$
**
****************************************************************************/
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 #include "piesliceitem_p.h"
Jani Honkonen
Rename piepresenter -> piechartitem
r568 #include "piechartitem_p.h"
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 #include "qpieseries.h"
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 #include "qpieslice.h"
Tero Ahola
Z order for pie
r490 #include "chartpresenter_p.h"
Tero Ahola
Integrated draft version of pie series
r51 #include <QPainter>
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 #include <qmath.h>
Jani Honkonen
Make pie work better with chartwidgettest
r163 #include <QGraphicsSceneEvent>
Jani Honkonen
Refactoring piechart API (and internals)
r174 #include <QTime>
Titta Heikkala
Add HTML support for pie slice labels...
r2626 #include <QTextDocument>
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 #include <QDebug>
Tero Ahola
Integrated draft version of pie series
r51
QTCOMMERCIALCHART_BEGIN_NAMESPACE
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 QPointF offset(qreal angle, qreal length)
{
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 qreal dx = qSin(angle * (M_PI / 180)) * length;
qreal dy = qCos(angle * (M_PI / 180)) * length;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 return QPointF(dx, -dy);
}
Jani Honkonen
more coding style fixes for src-folder...
r2104 PieSliceItem::PieSliceItem(QGraphicsItem *parent)
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 : QGraphicsObject(parent),
Marek Rosa
Added initial donut chart support to Pie series
r1670 m_hovered(false)
Tero Ahola
Integrated draft version of pie series
r51 {
setAcceptHoverEvents(true);
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 setAcceptedMouseButtons(Qt::MouseButtonMask);
Tero Ahola
Z order for pie
r490 setZValue(ChartPresenter::PieSeriesZValue);
Titta Heikkala
Add HTML support for pie slice labels...
r2626 m_labelItem = new QGraphicsTextItem(this);
m_labelItem->document()->setDocumentMargin(1.0);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 PieSliceItem::~PieSliceItem()
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 // If user is hovering over the slice and it gets destroyed we do
// not get a hover leave event. So we must emit the signal here.
if (m_hovered)
emit hovered(false);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QRectF PieSliceItem::boundingRect() const
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Refactoring pie series and animations.
r621 return m_boundingRect;
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QPainterPath PieSliceItem::shape() const
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Introducing vertical and horizontal factors to control the position of the pie.
r454 // Don't include the label and label arm.
// This is used to detect a mouse clicks. We do not want clicks from label.
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 return m_slicePath;
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*option*/, QWidget * /*widget*/)
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 painter->save();
Tero Ahola
Declarative series classed now derived from QSeries childs
r789 painter->setClipRect(parentItem()->boundingRect());
Jani Honkonen
Adding PIMPL to pie
r669 painter->setPen(m_data.m_slicePen);
painter->setBrush(m_data.m_sliceBrush);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 painter->drawPath(m_slicePath);
painter->restore();
Jani Honkonen
Fix setting custom color to pie. Now the pie knows if the color is set by the user.
r691 if (m_data.m_isLabelVisible) {
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 painter->save();
Jani Honkonen
pie: add label position to slice
r1450
Tero Ahola
Use labelBrush instead of labelPen for text labels
r1307 // Pen for label arm not defined in the QPieSeries api, let's use brush's color instead
Jani Honkonen
pie: add label position to slice
r1450 painter->setBrush(m_data.m_labelBrush);
Marek Rosa
Added one more type of label placing on Pie chart
r1712
Titta Heikkala
Add HTML support for pie slice labels...
r2626 if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
Jani Honkonen
pie: add label position to slice
r1450 painter->setClipRect(parentItem()->boundingRect());
painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color());
}
Tero Ahola
Fixed a bug with pie slice clip rect
r1297 painter->restore();
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 }
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::hoverEnterEvent(QGraphicsSceneHoverEvent * /*event*/)
Tero Ahola
Integrated draft version of pie series
r51 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 m_hovered = true;
Jani Honkonen
API review changes for pie
r1009 emit hovered(true);
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 void PieSliceItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * /*event*/)
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 {
Jani Honkonen
Emit hover leave signal from PieSliceItem when it gets destroyed....
r1083 m_hovered = false;
Jani Honkonen
API review changes for pie
r1009 emit hovered(false);
Tero Ahola
Integrated draft version of pie series
r51 }
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 void PieSliceItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
Jani Honkonen
Pie chart refactoring
r142 {
Jani Honkonen
Add mousebuttons to pie clicked signals
r707 emit clicked(event->buttons());
Michal Klocek
Fixes mouse handling in base class of chartseries
r1747 QGraphicsItem::mousePressEvent(event);
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 }
Jani Honkonen
Refactor graphical side of pie to simplify the implementation.
r1074 void PieSliceItem::setLayout(const PieSliceData &sliceData)
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 {
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 m_data = sliceData;
Jani Honkonen
Refactor graphical side of pie to simplify the implementation.
r1074 updateGeometry();
update();
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 void PieSliceItem::updateGeometry()
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 {
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 if (m_data.m_radius <= 0)
Jani Honkonen
Make pie fit better inside its given rectangle. Label texts still go outside. Needs a bit more work...
r289 return;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 prepareGeometryChange();
Jani Honkonen
pie: add label position to slice
r1450 // slice path
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 qreal centerAngle;
QPointF armStart;
Jani Honkonen
Rename PieSliceLayout -> PieSliceData. A "layout" is a bad name for this.
r668 m_slicePath = slicePath(m_data.m_center, m_data.m_radius, m_data.m_startAngle, m_data.m_angleSpan, &centerAngle, &armStart);
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157
Titta Heikkala
Fix pie slice label visibility and position on change...
r2628 m_labelItem->setVisible(m_data.m_isLabelVisible);
Titta Heikkala
Add HTML support for pie slice labels...
r2626 if (m_data.m_isLabelVisible) {
// text rect
m_labelTextRect = ChartPresenter::textBoundingRect(m_data.m_labelFont,
m_data.m_labelText,
0);
QString label(m_data.m_labelText);
m_labelItem->setDefaultTextColor(m_data.m_labelBrush.color());
m_labelItem->setFont(m_data.m_labelFont);
// text position
if (m_data.m_labelPosition == QPieSlice::LabelOutside) {
setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);
// label arm path
QPointF labelTextStart;
m_labelArmPath = labelArmPath(armStart, centerAngle,
m_data.m_radius * m_data.m_labelArmLengthFactor,
m_labelTextRect.width(), &labelTextStart);
m_labelTextRect.moveBottomLeft(labelTextStart);
if (m_labelTextRect.left() < 0)
m_labelTextRect.setLeft(0);
else if (m_labelTextRect.left() < parentItem()->boundingRect().left())
m_labelTextRect.setLeft(parentItem()->boundingRect().left());
if (m_labelTextRect.right() > parentItem()->boundingRect().right())
m_labelTextRect.setRight(parentItem()->boundingRect().right());
Titta Heikkala
Fix pie chart label truncation...
r2646 label = ChartPresenter::truncatedText(m_data.m_labelFont, m_data.m_labelText,
qreal(0.0), m_labelTextRect.width(),
m_labelTextRect.height(), m_labelTextRect);
m_labelArmPath = labelArmPath(armStart, centerAngle,
m_data.m_radius * m_data.m_labelArmLengthFactor,
m_labelTextRect.width(), &labelTextStart);
m_labelTextRect.moveBottomLeft(labelTextStart);
Titta Heikkala
Add HTML support for pie slice labels...
r2626
m_labelItem->setTextWidth(m_labelTextRect.width()
+ m_labelItem->document()->documentMargin());
m_labelItem->setHtml(label);
Titta Heikkala
Fix pie slice label rotation...
r2629 m_labelItem->setRotation(0);
Titta Heikkala
Add HTML support for pie slice labels...
r2626 m_labelItem->setPos(m_labelTextRect.x(), m_labelTextRect.y() + 1.0);
} else {
// label inside
setFlag(QGraphicsItem::ItemClipsChildrenToShape);
m_labelItem->setTextWidth(m_labelTextRect.width()
+ m_labelItem->document()->documentMargin());
m_labelItem->setHtml(label);
QPointF textCenter;
if (m_data.m_holeRadius > 0) {
textCenter = m_data.m_center + offset(centerAngle, m_data.m_holeRadius
+ (m_data.m_radius
- m_data.m_holeRadius) / 2);
} else {
textCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2);
}
m_labelItem->setPos(textCenter.x() - m_labelItem->boundingRect().width() / 2,
Titta Heikkala
Fix pie chart label truncation...
r2646 textCenter.y() - m_labelTextRect.height() / 2);
Titta Heikkala
Add HTML support for pie slice labels...
r2626
QPointF labelCenter = m_labelItem->boundingRect().center();
m_labelItem->setTransformOriginPoint(labelCenter);
if (m_data.m_labelPosition == QPieSlice::LabelInsideTangential) {
m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2);
} else if (m_data.m_labelPosition == QPieSlice::LabelInsideNormal) {
if (m_data.m_startAngle + m_data.m_angleSpan / 2 < 180)
m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 - 90);
else
m_labelItem->setRotation(m_data.m_startAngle + m_data.m_angleSpan / 2 + 90);
Titta Heikkala
Fix pie slice label visibility and position on change...
r2628 } else {
m_labelItem->setRotation(0);
Titta Heikkala
Add HTML support for pie slice labels...
r2626 }
}
Titta Heikkala
Fix pie slice label visibility...
r2655 // Hide label if it's outside the bounding rect of parent item
QRectF labelRect(m_labelItem->boundingRect());
labelRect.moveTopLeft(m_labelItem->pos());
if (parentItem()->boundingRect().contains(labelRect))
m_labelItem->show();
else
m_labelItem->hide();
Jani Honkonen
pie: add label position to slice
r1450 }
Jani Honkonen
Refactoring piechart API (and internals)
r174
Jani Honkonen
pie: add label position to slice
r1450 // bounding rect
Jani Honkonen
PieSliceItem bounding rect fix
r718 if (m_data.m_isLabelVisible)
m_boundingRect = m_slicePath.boundingRect().united(m_labelArmPath.boundingRect()).united(m_labelTextRect);
else
m_boundingRect = m_slicePath.boundingRect();
Miikka Heikkinen
Adjust pie slice bounding rectangle to account for thick pens...
r2454
// Inflate bounding rect by 2/3 pen width to make sure it encompasses whole slice also for thick pens
// and miter joins.
int penWidth = (m_data.m_slicePen.width() * 2) / 3;
m_boundingRect = m_boundingRect.adjusted(-penWidth, -penWidth, penWidth, penWidth);
Jani Honkonen
Refactor pie (again). QPieSlice's now emit signals and no id's anymore. Just pointers in the interface.
r203 }
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 QPointF PieSliceItem::sliceCenter(QPointF point, qreal radius, QPieSlice *slice)
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 {
if (slice->isExploded()) {
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 qreal centerAngle = slice->startAngle() + (slice->angleSpan() / 2);
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 qreal len = radius * slice->explodeDistanceFactor();
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 point += offset(centerAngle, len);
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 }
return point;
Jani Honkonen
Use signals from pieseries, visible hover and exploding slices
r157 }
Jani Honkonen
more coding style fixes for src-folder...
r2104 QPainterPath PieSliceItem::slicePath(QPointF center, qreal radius, qreal startAngle, qreal angleSpan, qreal *centerAngle, QPointF *armStart)
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 {
// calculate center angle
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 *centerAngle = startAngle + (angleSpan / 2);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// calculate slice rectangle
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 QRectF rect(center.x() - radius, center.y() - radius, radius * 2, radius * 2);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// slice path
QPainterPath path;
Marek Rosa
Donut support simplified. Examples updated
r1838 if (m_data.m_holeRadius > 0) {
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 QRectF insideRect(center.x() - m_data.m_holeRadius, center.y() - m_data.m_holeRadius, m_data.m_holeRadius * 2, m_data.m_holeRadius * 2);
Marek Rosa
Added initial donut chart support to Pie series
r1670 path.arcMoveTo(rect, -startAngle + 90);
path.arcTo(rect, -startAngle + 90, -angleSpan);
path.arcTo(insideRect, -startAngle + 90 - angleSpan, angleSpan);
path.closeSubpath();
} else {
path.moveTo(rect.center());
path.arcTo(rect, -startAngle + 90, -angleSpan);
path.closeSubpath();
}
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
// calculate label arm start point
*armStart = center;
Jani Honkonen
Refactoring the pie for animations (no actual animations yet)
r566 *armStart += offset(*centerAngle, radius + PIESLICE_LABEL_GAP);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
return path;
}
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length, qreal textWidth, QPointF *textStart)
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 {
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 // Normalize the angle to 0-360 range
// NOTE: We are using int here on purpose. Depenging on platform and hardware
// qreal can be a double, float or something the user gives to the Qt configure
// (QT_COORD_TYPE). Compilers do not seem to support modulo for double or float
// but there are fmod() and fmodf() functions for that. So instead of some #ifdef
// that might break we just use int. Precision for this is just fine for our needs.
int normalized = angle * 10.0;
normalized = normalized % 3600;
if (normalized < 0)
normalized += 3600;
angle = (qreal) normalized / 10.0;
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 // prevent label arm pointing straight down because it will look bad
if (angle < 180 && angle > 170)
angle = 170;
if (angle > 180 && angle < 190)
angle = 190;
// line from slice to label
Jani Honkonen
pieslice: fix slice labels turning the wrong way...
r1327 QPointF parm1 = start + offset(angle, length);
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437
Jani Honkonen
Prevent slice label pointing straight down (because it looks bad).
r972 // line to underline the label
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 QPointF parm2 = parm1;
if (angle < 180) { // arm swings the other way on the left side
Marek Rosa
Added initial donut chart support to Pie series
r1670 parm2 += QPointF(textWidth, 0);
*textStart = parm1;
Jani Honkonen
astyle and manual coding style fixes for src-folder
r2097 } else {
parm2 += QPointF(-textWidth, 0);
Marek Rosa
Added initial donut chart support to Pie series
r1670 *textStart = parm2;
Jani Honkonen
Added a pie chart customization example and refactoring the pie interface.
r437 }
QPainterPath path;
path.moveTo(start);
path.lineTo(parm1);
path.lineTo(parm2);
return path;
}
Jani Honkonen
rename PieSlice -> PieSliceItem
r673 #include "moc_piesliceitem_p.cpp"
Jani Honkonen
Refactoring piechart API (and internals)
r174
Tero Ahola
Integrated draft version of pie series
r51 QTCOMMERCIALCHART_END_NAMESPACE
Marek Rosa
Added insert, remove and other common methodds to QDonutGroup. Donut example added
r1693