piechartitem.cpp
189 lines
| 5.3 KiB
| text/x-c
|
CppLexer
Jani Honkonen
|
r568 | #include "piechartitem_p.h" | ||
Jani Honkonen
|
r353 | #include "pieslice_p.h" | ||
Jani Honkonen
|
r203 | #include "qpieslice.h" | ||
Jani Honkonen
|
r289 | #include "qpieseries.h" | ||
Tero Ahola
|
r490 | #include "chartpresenter_p.h" | ||
Jani Honkonen
|
r618 | #include "chartanimator_p.h" | ||
Jani Honkonen
|
r142 | #include <QDebug> | ||
Jani Honkonen
|
r437 | #include <QPainter> | ||
Jani Honkonen
|
r621 | #include <QTimer> | ||
Jani Honkonen
|
r142 | |||
QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||||
Jani Honkonen
|
r568 | PieChartItem::PieChartItem(QGraphicsItem *parent, QPieSeries *series) | ||
Jani Honkonen
|
r174 | :ChartItem(parent), | ||
m_series(series) | ||||
Jani Honkonen
|
r142 | { | ||
Q_ASSERT(series); | ||||
Jani Honkonen
|
r621 | connect(series, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleSlicesAdded(QList<QPieSlice*>))); | ||
connect(series, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleSlicesRemoved(QList<QPieSlice*>))); | ||||
connect(series, SIGNAL(piePositionChanged()), this, SLOT(handlePieLayoutChanged())); | ||||
connect(series, SIGNAL(pieSizeChanged()), this, SLOT(handlePieLayoutChanged())); | ||||
QTimer::singleShot(0, this, SLOT(initialize())); | ||||
Tero Ahola
|
r490 | |||
// Note: the following does not affect as long as the item does not have anything to paint | ||||
setZValue(ChartPresenter::PieSeriesZValue); | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | PieChartItem::~PieChartItem() | ||
Jani Honkonen
|
r142 | { | ||
Jani Honkonen
|
r174 | // slices deleted automatically through QGraphicsItem | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | void PieChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) | ||
Jani Honkonen
|
r142 | { | ||
Tero Ahola
|
r611 | Q_UNUSED(painter) | ||
Jani Honkonen
|
r174 | // TODO: paint shadows for all components | ||
// - get paths from items & merge & offset and draw with shadow color? | ||||
Jani Honkonen
|
r437 | //painter->setBrush(QBrush(Qt::red)); | ||
//painter->drawRect(m_debugRect); | ||||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r621 | void PieChartItem::initialize() | ||
{ | ||||
handleSlicesAdded(m_series->m_slices); | ||||
} | ||||
void PieChartItem::handleSlicesAdded(QList<QPieSlice*> slices) | ||||
{ | ||||
foreach (QPieSlice *s, slices) { | ||||
PieSlice* slice = new PieSlice(this); | ||||
m_slices.insert(s, slice); | ||||
connect(s, SIGNAL(changed()), this, SLOT(handleSliceChanged())); | ||||
connect(slice, SIGNAL(clicked()), s, SIGNAL(clicked())); | ||||
connect(slice, SIGNAL(hoverEnter()), s, SIGNAL(hoverEnter())); | ||||
connect(slice, SIGNAL(hoverLeave()), s, SIGNAL(hoverLeave())); | ||||
PieSliceLayout layout = calculateSliceLayout(s); | ||||
if (m_animator) | ||||
m_animator->addAnimation(this, s, layout); | ||||
else | ||||
setLayout(layout); | ||||
} | ||||
} | ||||
void PieChartItem::handleSlicesRemoved(QList<QPieSlice*> slices) | ||||
{ | ||||
foreach (QPieSlice *s, slices) { | ||||
if (m_animator) | ||||
m_animator->removeAnimation(this, s); | ||||
else | ||||
destroySlice(s); | ||||
} | ||||
} | ||||
void PieChartItem::handlePieLayoutChanged() | ||||
Jani Honkonen
|
r174 | { | ||
Jani Honkonen
|
r618 | QVector<PieSliceLayout> layout = calculateLayout(); | ||
applyLayout(layout); | ||||
Jani Honkonen
|
r566 | update(); | ||
} | ||||
Jani Honkonen
|
r142 | |||
Jani Honkonen
|
r568 | void PieChartItem::handleSliceChanged() | ||
Jani Honkonen
|
r566 | { | ||
Jani Honkonen
|
r618 | QPieSlice* slice = qobject_cast<QPieSlice *>(sender()); | ||
Q_ASSERT(m_slices.contains(slice)); | ||||
Jani Honkonen
|
r621 | PieSliceLayout layout = calculateSliceLayout(slice); | ||
updateLayout(layout); | ||||
Jani Honkonen
|
r566 | update(); | ||
Jani Honkonen
|
r203 | } | ||
Jani Honkonen
|
r174 | |||
Jani Honkonen
|
r568 | void PieChartItem::handleDomainChanged(qreal, qreal, qreal, qreal) | ||
Jani Honkonen
|
r203 | { | ||
// TODO | ||||
} | ||||
Jani Honkonen
|
r568 | void PieChartItem::handleGeometryChanged(const QRectF& rect) | ||
Jani Honkonen
|
r203 | { | ||
Jani Honkonen
|
r289 | prepareGeometryChange(); | ||
Jani Honkonen
|
r566 | m_rect = rect; | ||
Jani Honkonen
|
r621 | handlePieLayoutChanged(); | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r621 | void PieChartItem::calculatePieLayout() | ||
Jani Honkonen
|
r566 | { | ||
Jani Honkonen
|
r454 | // find pie center coordinates | ||
Jani Honkonen
|
r621 | m_pieCenter.setX(m_rect.left() + (m_rect.width() * m_series->pieHorizontalPosition())); | ||
m_pieCenter.setY(m_rect.top() + (m_rect.height() * m_series->pieVerticalPosition())); | ||||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r454 | // find maximum radius for pie | ||
Jani Honkonen
|
r621 | m_pieRadius = m_rect.height() / 2; | ||
Jani Honkonen
|
r454 | if (m_rect.width() < m_rect.height()) | ||
Jani Honkonen
|
r621 | m_pieRadius = m_rect.width() / 2; | ||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r454 | // apply size factor | ||
Jani Honkonen
|
r621 | m_pieRadius *= m_series->pieSize(); | ||
} | ||||
Jani Honkonen
|
r437 | |||
Jani Honkonen
|
r621 | PieSliceLayout PieChartItem::calculateSliceLayout(QPieSlice *slice) | ||
{ | ||||
PieSliceLayout sliceLayout; | ||||
sliceLayout.m_data = slice; | ||||
sliceLayout.m_center = PieSlice::sliceCenter(m_pieCenter, m_pieRadius, slice); | ||||
sliceLayout.m_radius = m_pieRadius; | ||||
sliceLayout.m_startAngle = slice->startAngle(); | ||||
sliceLayout.m_angleSpan = slice->m_angleSpan; | ||||
return sliceLayout; | ||||
} | ||||
QVector<PieSliceLayout> PieChartItem::calculateLayout() | ||||
{ | ||||
calculatePieLayout(); | ||||
Jani Honkonen
|
r566 | QVector<PieSliceLayout> layout; | ||
foreach (QPieSlice* s, m_series->slices()) { | ||||
Jani Honkonen
|
r621 | if (m_slices.contains(s)) // calculate layout only for those slices that are already visible | ||
layout << calculateSliceLayout(s); | ||||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r566 | return layout; | ||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r618 | void PieChartItem::applyLayout(QVector<PieSliceLayout> &layout) | ||
Jani Honkonen
|
r142 | { | ||
Jani Honkonen
|
r618 | if (m_animator) | ||
Jani Honkonen
|
r621 | m_animator->updateLayout(this, layout); | ||
Jani Honkonen
|
r618 | else | ||
setLayout(layout); | ||||
Jani Honkonen
|
r174 | } | ||
Jani Honkonen
|
r618 | void PieChartItem::updateLayout(PieSliceLayout &layout) | ||
{ | ||||
if (m_animator) | ||||
m_animator->updateLayout(this, layout); | ||||
else | ||||
setLayout(layout); | ||||
} | ||||
void PieChartItem::setLayout(QVector<PieSliceLayout> &layout) | ||||
Jani Honkonen
|
r289 | { | ||
Jani Honkonen
|
r566 | foreach (PieSliceLayout l, layout) { | ||
PieSlice *slice = m_slices.value(l.m_data); | ||||
Jani Honkonen
|
r621 | Q_ASSERT(slice); | ||
Jani Honkonen
|
r566 | slice->setLayout(l); | ||
Jani Honkonen
|
r621 | slice->updateData(l.m_data); | ||
Jani Honkonen
|
r566 | slice->updateGeometry(); | ||
slice->update(); | ||||
Jani Honkonen
|
r289 | } | ||
Jani Honkonen
|
r618 | } | ||
void PieChartItem::setLayout(PieSliceLayout &layout) | ||||
{ | ||||
// find slice | ||||
PieSlice *slice = m_slices.value(layout.m_data); | ||||
Jani Honkonen
|
r621 | Q_ASSERT(slice); | ||
Jani Honkonen
|
r618 | slice->setLayout(layout); | ||
if (m_series->m_slices.contains(layout.m_data)) // Slice has been deleted if not found. Animations ongoing... | ||||
slice->updateData(layout.m_data); | ||||
slice->updateGeometry(); | ||||
slice->update(); | ||||
} | ||||
void PieChartItem::destroySlice(QPieSlice *slice) | ||||
{ | ||||
delete m_slices.take(slice); | ||||
Jani Honkonen
|
r142 | } | ||
Jani Honkonen
|
r568 | #include "moc_piechartitem_p.cpp" | ||
Jani Honkonen
|
r142 | |||
QTCOMMERCIALCHART_END_NAMESPACE | ||||