Qt实现3D饼图,实现思路:采取画多个圆进行叠加实现3D的效果。
效果1:
代码实现:
void CPieWidget::drawDefault3DPie( QPainter *painter ) { qreal sum = getSumValue(); int radius = m_radius; //直径 //QRect rect = m_pierect;//(w/2-radius/2,h/2-radius/2,radius,radius); painter->save(); QPoint centerp = m_pierect.center(); QTransform tr; tr.translate(centerp.x(),centerp.y()); tr.rotate(-20,Qt::ZAxis); tr.rotate(0,Qt::YAxis); painter->setTransform(tr); QRect rect(-radius/2,-radius/2,radius,radius); //画底图 int dep = 20/*radius/30*/; QPen pen; pen.setWidthF(0.2); painter->setPen(pen); //painter->setPen(Qt::NoPen); QStringList keylist = m_datamap.keys(); for (int j = 0 ; j < dep; ++j) { qreal index = 30; //启始位置 int colorindex = 0; for (int i = 0; i < keylist.count(); ++i) { qreal v = m_datamap.value(keylist.at(i)); v =v/sum*(360); QRect newrect = rect; if (m_explodedindex == i || m_isexploded) { QPoint newcenter = newrect.center(); int midangel = index+v/2; QPoint tp = getMovePoint(midangel); newcenter += tp; newrect.moveCenter(newcenter); } QPoint cp = newrect.center() + QPoint(j/2,-j); newrect.moveCenter(cp); QPoint centerPoint = newrect.center(); QColor firstColor = m_colorlist.at(colorindex); QRadialGradient firstGradient(centerPoint, radius/2); if (j == 19) { firstGradient.setColorAt(0, firstColor.lighter(120)); firstGradient.setColorAt(1.0, firstColor.lighter(100)); } else firstGradient.setColorAt(1.0, firstColor.dark(150)); painter->setBrush(firstGradient); painter->drawPie(newrect, index * 16, v * 16); index+=v; colorindex++; if (colorindex==m_colorlist.count()) { colorindex = 0; } } } painter->restore(); }效果2:
代码如下:
void CPieWidget::drawDount3DPie( QPainter *painter ) { qreal sum = getSumValue(); int radius = m_radius; //直径 QPoint centerp = m_pierect.center(); painter->save(); QTransform tr; tr.translate(centerp.x(),centerp.y()); tr.rotate(-20,Qt::ZAxis); tr.rotate(0,Qt::YAxis); painter->setTransform(tr); //QRect rect(w/2-radius/2,h/2-radius/2,radius,radius); QRect rect(-radius/2,-radius/2,radius,radius); //画底图 int dep = 20/*radius/30*/; QPen pen; pen.setWidthF(0.2); painter->setPen(pen); painter->setPen(Qt::NoPen); QStringList keylist = m_datamap.keys(); for (int j = 0 ; j < dep; ++j) { qreal index = 30; //启始位置 int colorindex = 0; for (int i = 0; i < keylist.count(); ++i) { qreal v = m_datamap.value(keylist.at(i)); v =v/sum*(360); QRect newrect = rect; if (m_explodedindex == i || m_isexploded) { QPoint newcenter = newrect.center(); int midangel = index+v/2; QPoint tp = getMovePoint(midangel); newcenter += tp; newrect.moveCenter(newcenter); } QPoint cp = newrect.center() + QPoint(j/2,-j); newrect.moveCenter(cp); QPoint centerPoint = newrect.center(); QColor firstColor = m_colorlist.at(colorindex); QRadialGradient firstGradient(centerPoint, radius/2); firstGradient.setColorAt(0, Qt::transparent); firstGradient.setColorAt(0.6, Qt::transparent); if (j == 19) { firstGradient.setColorAt(0.61, firstColor.lighter(120)); firstGradient.setColorAt(1.0, firstColor.lighter(100)); } else { firstGradient.setColorAt(0.61, firstColor.dark(120)); firstGradient.setColorAt(1.0, firstColor.dark(150)); } painter->setBrush(firstGradient); painter->drawPie(newrect, index * 16, v * 16); index+=v; colorindex++; if (colorindex==m_colorlist.count()) { colorindex = 0; } } } painter->restore(); }
QHash
QList
QRect m_pierect;
QRect m_legendrect;
int m_radius;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
这种方式实现可能会影响效率,因为循环画了多次。