mirror of
https://github.com/fralx/LimeReport.git
synced 2024-12-24 00:33:02 +03:00
0fca7169d3
except those placed in 3rdparty directories.
167 lines
6.2 KiB
C++
167 lines
6.2 KiB
C++
#include "lrpiechart.h"
|
|
|
|
namespace LimeReport {
|
|
|
|
void PieChart::drawPercent(QPainter* painter, QRectF chartRect, qreal startAngle, qreal angle)
|
|
{
|
|
painter->save();
|
|
|
|
QPointF center(chartRect.left() + chartRect.width() / 2,
|
|
chartRect.top() + chartRect.height() / 2);
|
|
qreal percent = angle / 3.6;
|
|
#if QT_VERSION < 0x050000
|
|
qreal radAngle = (angle / 2 + startAngle) * (M_PI / 180);
|
|
#else
|
|
qreal radAngle = qDegreesToRadians(angle / 2 + startAngle);
|
|
#endif
|
|
qreal radius = painter->fontMetrics().boundingRect("99,9%").width();
|
|
qreal border = chartRect.height() * 0.02;
|
|
qreal length = (chartRect.height()) / 2 - (radius / 2 + border);
|
|
qreal x, y;
|
|
x = length * qCos(radAngle);
|
|
y = length * qSin(radAngle);
|
|
QPointF endPoint(center.x() + x, center.y() - y);
|
|
painter->setPen(Qt::white);
|
|
QRectF textRect(endPoint.x() - (radius / 2), endPoint.y() - (radius / 2), radius, radius);
|
|
|
|
qreal arcLength = 3.14 * length * angle / 180;
|
|
if (arcLength >= radius)
|
|
painter->drawText(textRect, Qt::AlignCenter, QString::number(percent, 'f', 1) + "%");
|
|
painter->restore();
|
|
}
|
|
|
|
void PieChart::paintChart(QPainter* painter, QRectF chartRect)
|
|
{
|
|
painter->save();
|
|
QPen pen(Qt::white);
|
|
pen.setWidthF(2);
|
|
painter->setPen(pen);
|
|
|
|
QBrush brush(Qt::transparent);
|
|
painter->setBrush(brush);
|
|
painter->setBackground(QBrush(Qt::NoBrush));
|
|
|
|
QRectF tmpRect = chartRect;
|
|
if (chartRect.height() > chartRect.width()) {
|
|
tmpRect.setHeight(chartRect.width());
|
|
tmpRect.adjust(0, (chartRect.bottom() - tmpRect.bottom()) / 2, 0,
|
|
(chartRect.bottom() - tmpRect.bottom()) / 2);
|
|
} else {
|
|
tmpRect.setWidth(chartRect.height());
|
|
}
|
|
|
|
chartRect = tmpRect;
|
|
painter->drawRect(chartRect);
|
|
|
|
if (!m_chartItem->series().isEmpty()
|
|
&& !m_chartItem->series().at(0)->data()->values().isEmpty()) {
|
|
SeriesItem* si = m_chartItem->series().at(0);
|
|
qreal sum = 0;
|
|
foreach (qreal value, si->data()->values()) {
|
|
sum += value;
|
|
}
|
|
qreal onePercent = sum / 100;
|
|
qreal currentDegree = 0;
|
|
for (int i = 0; i < si->data()->values().count(); ++i) {
|
|
qreal value = si->data()->values().at(i);
|
|
qreal sectorDegree = (value / onePercent) * 3.6;
|
|
painter->setBrush(si->data()->colors().at(i));
|
|
painter->drawPie(chartRect, currentDegree * 16, sectorDegree * 16);
|
|
drawPercent(painter, chartRect, currentDegree, sectorDegree);
|
|
currentDegree += sectorDegree;
|
|
}
|
|
} else if (m_chartItem->itemMode() == DesignMode) {
|
|
painter->setBrush(color_map[0]);
|
|
painter->drawPie(chartRect, 0, 260 * 16);
|
|
drawPercent(painter, chartRect, 0, 260);
|
|
painter->setBrush(color_map[1]);
|
|
painter->drawPie(chartRect, 260 * 16, 40 * 16);
|
|
drawPercent(painter, chartRect, 260, 40);
|
|
painter->setBrush(color_map[2]);
|
|
painter->drawPie(chartRect, 300 * 16, 60 * 16);
|
|
drawPercent(painter, chartRect, 300, 60);
|
|
}
|
|
|
|
pen.setWidthF(1);
|
|
pen.setColor(Qt::gray);
|
|
painter->setPen(pen);
|
|
painter->setBrush(Qt::NoBrush);
|
|
painter->drawEllipse(chartRect);
|
|
painter->restore();
|
|
}
|
|
|
|
void PieChart::paintChartLegend(QPainter* painter, QRectF legendRect)
|
|
{
|
|
prepareLegendToPaint(legendRect, painter);
|
|
|
|
int indicatorSize = painter->fontMetrics().height() / 2;
|
|
painter->setRenderHint(QPainter::Antialiasing, false);
|
|
|
|
if (m_chartItem->drawLegendBorder())
|
|
painter->drawRect(legendRect);
|
|
|
|
painter->setRenderHint(QPainter::Antialiasing, true);
|
|
QRectF indicatorsRect = legendRect.adjusted(painter->fontMetrics().height() / 2,
|
|
painter->fontMetrics().height() / 2, 0, 0);
|
|
|
|
if (!m_chartItem->series().isEmpty()
|
|
&& !m_chartItem->series().at(0)->data()->labels().isEmpty()) {
|
|
qreal cw = 0;
|
|
SeriesItem* si = m_chartItem->series().at(0);
|
|
for (int i = 0; i < si->data()->labels().count(); ++i) {
|
|
QString label = si->data()->labels().at(i);
|
|
painter->setPen(Qt::black);
|
|
painter->drawText(indicatorsRect.adjusted(indicatorSize + indicatorSize / 2, cw, 0, 0),
|
|
label);
|
|
painter->setPen(si->data()->colors().at(i));
|
|
painter->setBrush(si->data()->colors().at(i));
|
|
painter->drawEllipse(indicatorsRect.adjusted(
|
|
0, cw + indicatorSize / 2, -(indicatorsRect.width() - indicatorSize),
|
|
-(indicatorsRect.height() - (cw + indicatorSize + indicatorSize / 2))));
|
|
cw += painter->fontMetrics().height();
|
|
}
|
|
} else if (m_chartItem->itemMode() == DesignMode) {
|
|
qreal cw = 0;
|
|
for (int i = 0; i < m_designLabels.size(); ++i) {
|
|
QString label = m_designLabels.at(i);
|
|
painter->setPen(Qt::black);
|
|
painter->drawText(indicatorsRect.adjusted(indicatorSize + indicatorSize / 2, cw, 0, 0),
|
|
label);
|
|
painter->setBrush(color_map[i]);
|
|
painter->setPen(color_map[i]);
|
|
painter->drawEllipse(indicatorsRect.adjusted(
|
|
0, cw + indicatorSize / 2, -(indicatorsRect.width() - indicatorSize),
|
|
-(indicatorsRect.height() - (cw + indicatorSize + indicatorSize / 2))));
|
|
cw += painter->fontMetrics().height();
|
|
}
|
|
}
|
|
}
|
|
|
|
QSizeF PieChart::calcChartLegendSize(const QFont& font, qreal)
|
|
{
|
|
QFontMetrics fm(font);
|
|
|
|
qreal cw = 0;
|
|
qreal maxWidth = 0;
|
|
|
|
if (!m_chartItem->series().isEmpty()
|
|
&& !m_chartItem->series().at(0)->data()->labels().isEmpty()) {
|
|
SeriesItem* si = m_chartItem->series().at(0);
|
|
foreach (QString label, si->data()->labels()) {
|
|
cw += fm.height();
|
|
if (maxWidth < fm.boundingRect(label).width())
|
|
maxWidth = fm.boundingRect(label).width() + 10;
|
|
}
|
|
} else {
|
|
foreach (QString label, m_designLabels) {
|
|
cw += fm.height();
|
|
if (maxWidth < fm.boundingRect(label).width())
|
|
maxWidth = fm.boundingRect(label).width() + 10;
|
|
}
|
|
}
|
|
cw += fm.height();
|
|
return QSizeF(maxWidth + fm.height() * 2, cw);
|
|
}
|
|
|
|
} // namespace LimeReport
|