diff --git a/examples/donut/donut.pro b/examples/donut/donut.pro new file mode 100644 index 0000000..3d6a77e --- /dev/null +++ b/examples/donut/donut.pro @@ -0,0 +1,8 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +TARGET = donut +SOURCES += main.cpp\ + widget.cpp +HEADERS += widget.h diff --git a/examples/donut/main.cpp b/examples/donut/main.cpp new file mode 100644 index 0000000..7b1f424 --- /dev/null +++ b/examples/donut/main.cpp @@ -0,0 +1,11 @@ +#include +#include "widget.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + Widget w; + w.show(); + + return a.exec(); +} diff --git a/examples/donut/widget.cpp b/examples/donut/widget.cpp new file mode 100644 index 0000000..19fb1cf --- /dev/null +++ b/examples/donut/widget.cpp @@ -0,0 +1,65 @@ +#include "widget.h" +#include +#include +#include +#include +#include +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +Widget::Widget(QWidget *parent) + : QWidget(parent) +{ + setMinimumSize(800, 600); + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + QChartView *chartView = new QChartView; + chartView->setRenderHint(QPainter::Antialiasing); + + for (int i = 0; i < 7; i++) { + QPieSeries *donut = new QPieSeries; + donut->setLabelsVisible(); + for (int j = 0; j < 4; j++) { + qreal value = 100 + qrand() % 100; + donut->append(QString("%1").arg(value), value); + donut->slices().last()->setLabelVisible(true); +// QFont labelFont = donut->slices().last()->labelFont(); +// // labelFont.setUnderline(true); +// labelFont.setBold(true); +// donut->slices().last()->setLabelFont(labelFont); + donut->slices().last()->setLabelColor(Qt::white); + } + qreal phase = qrand() % 180; + donut->setPieStartAngle(phase); + donut->setPieEndAngle(360 + phase); + chartView->chart()->addSeries(donut); + m_donutsGroup.append(donut); + } + + // create main layout + QGridLayout* mainLayout = new QGridLayout; + mainLayout->addWidget(chartView, 1, 1); + setLayout(mainLayout); + + chartView->chart()->setAnimationOptions(QChart::AllAnimations); + + QTimer *updateTimer = new QTimer(this); + connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateRotation())); + updateTimer->start(750); +} + +Widget::~Widget() +{ + +} + +void Widget::updateRotation() +{ + for (int i = 0; i < m_donutsGroup.count(); i++) { + QPieSeries *donut = m_donutsGroup.donuts().at(i); + qreal phaseShift = -50 + qrand() % 100; + donut->setPieStartAngle(donut->pieStartAngle() + phaseShift); + donut->setPieEndAngle(donut->pieEndAngle() + phaseShift); + } +} diff --git a/examples/donut/widget.h b/examples/donut/widget.h new file mode 100644 index 0000000..cc1ab07 --- /dev/null +++ b/examples/donut/widget.h @@ -0,0 +1,24 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +class Widget : public QWidget +{ + Q_OBJECT + +public: + Widget(QWidget *parent = 0); + ~Widget(); + +public slots: + void updateRotation(); + +private: + QDonutGroup m_donutsGroup; +}; + +#endif // WIDGET_H diff --git a/examples/examples.pro b/examples/examples.pro index 0a1e17a..a30cbb0 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -26,4 +26,5 @@ SUBDIRS += \ lineandbar \ horizontalbarchart \ horizontalstackedbarchart \ - horizontalpercentbarchart + horizontalpercentbarchart \ + donut diff --git a/src/piechart/piesliceitem.cpp b/src/piechart/piesliceitem.cpp index ff6a50a..3ed0bba 100644 --- a/src/piechart/piesliceitem.cpp +++ b/src/piechart/piesliceitem.cpp @@ -84,13 +84,17 @@ void PieSliceItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*op painter->setPen(m_data.m_labelBrush.color()); painter->setBrush(m_data.m_labelBrush); painter->setFont(m_data.m_labelFont); - if (m_data.m_labelPosition == QPieSlice::LabelOutside) { + if (m_data.m_donut) { + painter->translate(m_labelTextRect.center()); + painter->rotate(m_data.m_startAngle + m_data.m_angleSpan / 2); + painter->drawText(-m_labelTextRect.width() / 2, -m_labelTextRect.height() / 2, m_labelTextRect.width(), m_labelTextRect.height(), Qt::AlignCenter, m_data.m_labelText); + }else if (m_data.m_labelPosition == QPieSlice::LabelOutside) { painter->setClipRect(parentItem()->boundingRect()); painter->strokePath(m_labelArmPath, m_data.m_labelBrush.color()); } else { // QPieSlice::LabelInside painter->setClipPath(m_slicePath); + painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText); } - painter->drawText(m_labelTextRect, Qt::AlignCenter, m_data.m_labelText); painter->restore(); } @@ -141,9 +145,12 @@ void PieSliceItem::updateGeometry() m_labelArmPath = labelArmPath(armStart, centerAngle, m_data.m_radius * m_data.m_labelArmLengthFactor, m_labelTextRect.width(), &labelTextStart); // text position - if (m_data.m_labelPosition == QPieSlice::LabelOutside) + if (m_data.m_donut) { + QPointF donutCenter = m_data.m_center + offset(centerAngle, m_data.m_innerRadius + (m_data.m_radius - m_data.m_innerRadius) / 2); + m_labelTextRect.moveCenter(donutCenter); + } else if (m_data.m_labelPosition == QPieSlice::LabelOutside) { m_labelTextRect.moveBottomLeft(labelTextStart); - else {// QPieSlice::LabelInside + } else {// QPieSlice::LabelInside QPointF sliceCenter = m_data.m_center + offset(centerAngle, m_data.m_radius / 2); m_labelTextRect.moveCenter(sliceCenter); } @@ -239,3 +246,4 @@ QPainterPath PieSliceItem::labelArmPath(QPointF start, qreal angle, qreal length #include "moc_piesliceitem_p.cpp" QTCOMMERCIALCHART_END_NAMESPACE + diff --git a/src/piechart/qdonutgroup.cpp b/src/piechart/qdonutgroup.cpp index e930a3d..c958a55 100644 --- a/src/piechart/qdonutgroup.cpp +++ b/src/piechart/qdonutgroup.cpp @@ -11,17 +11,53 @@ QDonutGroup::QDonutGroup(QObject *parent) : void QDonutGroup::append(QPieSeries *donut) { + insert(count(), donut); +} + +bool QDonutGroup::insert(int index, QPieSeries* donut) +{ if (donut == 0) - return; + return false; donut->setDonut(); Q_D(QDonutGroup); - d->m_donuts.append(donut); + d->m_donuts.insert(index, donut); qreal donutFraction = 1.0 / (d->m_donuts.count() + 1); for(int i = 0; i < d->m_donuts.count(); i++) { d->m_donuts[i]->setPieSize( (i + 2) * donutFraction); d->m_donuts[i]->setDonutInnerSize( (i + 1) * donutFraction); } + return true; +} + +bool QDonutGroup::remove(QPieSeries* donut) +{ + Q_D(QDonutGroup); + int index = d->m_donuts.indexOf(donut); + if (index == -1) + return false; + else + d->m_donuts.removeOne(donut); + + return true; +} + +void QDonutGroup::clear() +{ + Q_D(QDonutGroup); + d->m_donuts.clear(); +} + +QList QDonutGroup::donuts() const +{ + Q_D(const QDonutGroup); + return d->m_donuts; +} + +int QDonutGroup::count() const +{ + Q_D(const QDonutGroup); + return d->m_donuts.count(); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/piechart/qdonutgroup.h b/src/piechart/qdonutgroup.h index e25abb0..9de5760 100644 --- a/src/piechart/qdonutgroup.h +++ b/src/piechart/qdonutgroup.h @@ -17,6 +17,14 @@ public: void append(QPieSeries *donut); + bool insert(int index, QPieSeries* donut); + + bool remove(QPieSeries* donut); + void clear(); + + QList donuts() const; + int count() const; + protected: QDonutGroupPrivate * const d_ptr; Q_DECLARE_PRIVATE(QDonutGroup)