#include "pieslice.h" #include "pieslicelabel.h" #include "piepresenter.h" #include "qpieseries.h" #include #include #include #include #include QTCOMMERCIALCHART_BEGIN_NAMESPACE #define PI 3.14159265 #define EXPLODE_OFFSET 20 QPointF offset(qreal angle, qreal length) { qreal dx = qSin(angle*(PI/180)) * length; qreal dy = qCos(angle*(PI/180)) * length; return QPointF(dx, -dy); } PieSlice::PieSlice(QPieSliceId id, QPieSeries *series, QGraphicsItem* parent) :QGraphicsObject(parent), m_id(id), m_series(series), m_slicelabel(new PieSliceLabel(this)), m_isHovering(false) { Q_ASSERT(series); setAcceptHoverEvents(true); setAcceptedMouseButtons(Qt::LeftButton); updateData(); } PieSlice::~PieSlice() { qDebug() << "~PieSlice()" << m_id; } QRectF PieSlice::boundingRect() const { return m_rect; } QPainterPath PieSlice::shape() const { return m_path; } void PieSlice::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) { // set hover brush // TODO: what if we are using gradients... QBrush brush = m_data.brush(); if (m_isHovering) brush.setColor(brush.color().lighter()); painter->setRenderHint(QPainter::Antialiasing); painter->setPen(m_data.pen()); painter->setBrush(brush); painter->drawPath(m_path); } void PieSlice::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) { m_isHovering = true; update(); // TODO: emit hoverEnter() } void PieSlice::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) { m_isHovering = false; update(); // TODO: emit hoverLeave() } void PieSlice::mousePressEvent(QGraphicsSceneMouseEvent* /*event*/) { // TODO: emit clicked // TODO: should we let the user decide if this can be exploded? m_data.setExploded(!m_data.isExploded()); m_series->update(m_data); } void PieSlice::updateGeometry(QRectF rect, qreal startAngle, qreal span) { prepareGeometryChange(); // calculate center angle qreal centerAngle = startAngle + (span/2); // adjust rect for exploding rect.adjust(EXPLODE_OFFSET, EXPLODE_OFFSET, -EXPLODE_OFFSET ,-EXPLODE_OFFSET); if (m_data.isExploded()) { QPointF d = offset((centerAngle), EXPLODE_OFFSET); rect.translate(d.x(), d.y()); } // update slice path // TODO: draw the shape so that it might have a hole in the center QPainterPath path; path.moveTo(rect.center()); path.arcTo(rect, -startAngle + 90, -span); m_path = path; m_rect = path.boundingRect(); // update label position qreal radius = rect.height() / 2; QPointF edgeCenter = rect.center() + offset(centerAngle, radius + 5); m_slicelabel->setArmStartPoint(edgeCenter); m_slicelabel->setArmAngle(centerAngle); m_slicelabel->setArmLength(50); m_slicelabel->updateGeometry(); //qDebug() << "PieSlice::updateGeometry" << m_rect; } void PieSlice::updateData() { if (!m_series->m_slices.contains(m_id)) qWarning() << "PieSlice::updateData(): cannot find slice data!" << m_id; QPieSlice data = m_series->slice(m_id); // TODO: find out what has changed and trigger some animation m_data = data; update(); m_slicelabel->setVisible(m_data.isLabelVisible()); m_slicelabel->setText(m_data.label()); //m_slicelabel->setPen(m_data.labelPen()); //m_slicelabel->setFont(m_data.labelFont()); m_slicelabel->updateGeometry(); // text size & font modifies the geometry m_slicelabel->update(); } #include "moc_pieslice.cpp" QTCOMMERCIALCHART_END_NAMESPACE