Add horizontal legend

This commit is contained in:
Emil Sawicki 2022-02-07 23:16:07 +01:00
parent 667ff4adb4
commit b14f0be7bc
4 changed files with 325 additions and 90 deletions

View File

@ -91,6 +91,7 @@ void PieChart::paintChart(QPainter *painter, QRectF chartRect)
void PieChart::paintChartLegend(QPainter *painter, QRectF legendRect) void PieChart::paintChartLegend(QPainter *painter, QRectF legendRect)
{ {
// TODO_ES Fix bottom legend when axis is at the bottom
prepareLegendToPaint(legendRect, painter); prepareLegendToPaint(legendRect, painter);
int indicatorSize = painter->fontMetrics().height()/2; int indicatorSize = painter->fontMetrics().height()/2;
@ -143,7 +144,7 @@ void PieChart::paintChartLegend(QPainter *painter, QRectF legendRect)
} }
} }
QSizeF PieChart::calcChartLegendSize(const QFont &font) QSizeF PieChart::calcChartLegendSize(const QFont &font, qreal)
{ {
QFontMetrics fm(font); QFontMetrics fm(font);

View File

@ -8,7 +8,7 @@ namespace LimeReport{
class PieChart : public AbstractChart{ class PieChart : public AbstractChart{
public: public:
PieChart(ChartItem* chartItem):AbstractChart(chartItem){} PieChart(ChartItem* chartItem):AbstractChart(chartItem){}
QSizeF calcChartLegendSize(const QFont &font); QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth = 0);
void paintChart(QPainter *painter, QRectF chartRect); void paintChart(QPainter *painter, QRectF chartRect);
void paintChartLegend(QPainter *painter, QRectF legendRect); void paintChartLegend(QPainter *painter, QRectF legendRect);
protected: protected:

View File

@ -141,10 +141,11 @@ void SeriesItem::setPreferredType(const SeriesItemPreferredType& type)
ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent) ChartItem::ChartItem(QObject *owner, QGraphicsItem *parent)
: ItemDesignIntf(xmlTag, owner, parent), m_legendBorder(true), : ItemDesignIntf(xmlTag, owner, parent), m_legendBorder(true),
m_legendAlign(LegendAlignCenter), m_titleAlign(TitleAlignCenter), m_legendAlign(LegendAlignRightCenter), m_titleAlign(TitleAlignCenter),
m_chartType(Pie), m_labelsField(""), m_isEmpty(true), m_chartType(Pie), m_labelsField(""), m_isEmpty(true),
m_showLegend(true), m_drawPoints(true), m_seriesLineWidth(4), m_showLegend(true), m_drawPoints(true), m_seriesLineWidth(4),
m_horizontalAxisOnTop(false), m_gridChartLines(AllLines) m_horizontalAxisOnTop(false), m_gridChartLines(AllLines),
m_legendStyle(LegendPoints)
{ {
m_labels<<"First"<<"Second"<<"Thrid"; m_labels<<"First"<<"Second"<<"Thrid";
m_chart = new PieChart(this); m_chart = new PieChart(this);
@ -195,11 +196,28 @@ void ChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
} }
const QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset); const QRectF titleRect = QRectF(borderMargin,borderMargin,rect().width()-borderMargin*2,titleOffset);
QRectF legendRect = QRectF(0,0,0,0); QRectF legendRect = QRectF(0, 0, 0, 0);
if (m_showLegend) QRectF diagramRect = QRectF(0, 0, 0, 0);
if (m_showLegend) {
legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset); legendRect = m_chart->calcChartLegendRect(painter->font(), rect(), false, borderMargin, titleOffset);
QRectF diagramRect = rect().adjusted(borderMargin,titleOffset+borderMargin, switch(legendAlign()) {
-(legendRect.width()+borderMargin*2),-borderMargin); case LegendAlignRightTop:
case LegendAlignRightBottom:
case LegendAlignRightCenter:
diagramRect = rect().adjusted(borderMargin, titleOffset + borderMargin,
-(legendRect.width() + borderMargin * 2), -borderMargin);
break;
case LegendAlignBottomLeft:
case LegendAlignBottomCenter:
case LegendAlignBottomRight:
diagramRect = rect().adjusted(borderMargin, titleOffset + borderMargin,
(borderMargin * 2), -legendRect.height());
break;
}
} else {
diagramRect = rect().adjusted(borderMargin, titleOffset + borderMargin,
-(borderMargin * 2), -borderMargin);
}
paintChartTitle(painter, titleRect); paintChartTitle(painter, titleRect);
if (m_showLegend) if (m_showLegend)
@ -414,6 +432,22 @@ void ChartItem::setLegendAlign(const LegendAlign &legendAlign)
} }
} }
ChartItem::LegendStyle ChartItem::legendStyle() const
{
return m_legendStyle;
}
void ChartItem::setLegendStyle(const LegendStyle &legendStyle)
{
if (m_legendStyle == legendStyle) {
return;
}
LegendStyle oldValue = m_legendStyle;
m_legendStyle = legendStyle;
notify("legendStyle", oldValue, m_legendStyle);
update();
}
bool ChartItem::drawLegendBorder() const bool ChartItem::drawLegendBorder() const
{ {
return m_legendBorder; return m_legendBorder;
@ -571,37 +605,61 @@ AbstractChart::AbstractChart(ChartItem *chartItem)
QRectF AbstractChart::calcChartLegendRect(const QFont &font, const QRectF &parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset) QRectF AbstractChart::calcChartLegendRect(const QFont &font, const QRectF &parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset)
{ {
QSizeF legendSize = calcChartLegendSize(font); const QSizeF legendSize = calcChartLegendSize(font, parentRect.width() * 0.9);
qreal legendTopMargin = 0; qreal legendTopMargin = 0;
qreal legendBottomMargin = 0; qreal legendBottomMargin = 0;
qreal legendLeftMargin = 0;
bool isVertical = true;
switch (m_chartItem->legendAlign()) { switch (m_chartItem->legendAlign()) {
case ChartItem::LegendAlignTop: case ChartItem::LegendAlignRightTop:
legendTopMargin = titleOffset+borderMargin; legendTopMargin = titleOffset + borderMargin;
legendBottomMargin = parentRect.height()-(legendSize.height()+titleOffset); legendBottomMargin = parentRect.height() - (legendSize.height() + titleOffset);
isVertical = true;
break; break;
case ChartItem::LegendAlignCenter: case ChartItem::LegendAlignRightCenter:
legendTopMargin = titleOffset+(parentRect.height()-titleOffset-legendSize.height())/2; legendTopMargin = titleOffset + (parentRect.height() - titleOffset - legendSize.height()) / 2;
legendBottomMargin = (parentRect.height()-titleOffset-legendSize.height())/2; legendBottomMargin = (parentRect.height() - titleOffset - legendSize.height()) / 2;
isVertical = true;
break; break;
case ChartItem::LegendAlignBottom: case ChartItem::LegendAlignRightBottom:
legendTopMargin = parentRect.height()-(legendSize.height()+titleOffset); legendTopMargin = parentRect.height() - (legendSize.height() + titleOffset);
legendBottomMargin = borderMargin; legendBottomMargin = borderMargin;
isVertical = true;
break;
case ChartItem::LegendAlignBottomLeft:
legendLeftMargin = QFontMetrics(font).height() / 2;
isVertical = false;
break;
case ChartItem::LegendAlignBottomCenter:
legendLeftMargin = (parentRect.width() - legendSize.width()) / 2;
isVertical = false;
break;
case ChartItem::LegendAlignBottomRight:
legendLeftMargin = parentRect.width() - legendSize.width() - QFontMetrics(font).height() / 2;
isVertical = false;
break; break;
} }
qreal rightOffset = !takeAllRect?((legendSize.width()>parentRect.width()/2-borderMargin)? if (isVertical) {
(parentRect.width()/2): qreal rightOffset = !takeAllRect ? ((legendSize.width() > parentRect.width() / 2 - borderMargin) ?
(parentRect.width()-legendSize.width())):0; (parentRect.width() / 2) :
(parentRect.width() - legendSize.width())) : 0;
QRectF legendRect = parentRect.adjusted( return parentRect.adjusted(
rightOffset, rightOffset,
(legendSize.height()>(parentRect.height()-titleOffset))?(titleOffset):(legendTopMargin), (legendSize.height()>(parentRect.height()-titleOffset))?(titleOffset):(legendTopMargin),
-borderMargin, -borderMargin,
(legendSize.height()>(parentRect.height()-titleOffset))?(0):(-legendBottomMargin) (legendSize.height()>(parentRect.height()-titleOffset))?(0):(-legendBottomMargin)
); );
} else {
return legendRect; const qreal verticalOffset = borderMargin * 2;
return parentRect.adjusted(
legendLeftMargin,
(parentRect.height()) - (legendSize.height() + verticalOffset),
-(parentRect.width() - (legendSize.width() + legendLeftMargin)),
-verticalOffset
);
}
} }
@ -618,18 +676,28 @@ void AbstractChart::setTitleFont(const QFont &value)
void AbstractChart::prepareLegendToPaint(QRectF &legendRect, QPainter *painter) void AbstractChart::prepareLegendToPaint(QRectF &legendRect, QPainter *painter)
{ {
QFont tmpFont = painter->font(); QFont tmpFont = painter->font();
QSizeF legendSize = calcChartLegendSize(tmpFont); switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
if ((legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width())){ case ChartItem::LegendAlignBottomCenter:
while ( (legendSize.height()>legendRect.height() || legendSize.width()>legendRect.width()) case ChartItem::LegendAlignBottomRight: {
&& tmpFont.pixelSize()>1) // TODO_ES handle resize horizontal legend (wrapping text)
{ break;
tmpFont.setPixelSize(tmpFont.pixelSize()-1); }
case ChartItem::LegendAlignRightTop:
case ChartItem::LegendAlignRightCenter:
case ChartItem::LegendAlignRightBottom:
QSizeF legendSize = calcChartLegendSize(tmpFont, legendRect.width());
if ((legendSize.height() > legendRect.height() || legendSize.width() > legendRect.width())) {
while ( (legendSize.height() > legendRect.height() || legendSize.width() > legendRect.width())
&& tmpFont.pixelSize() > 1)
{
tmpFont.setPixelSize(tmpFont.pixelSize()-1);
legendSize = calcChartLegendSize(tmpFont, legendRect.width());
}
painter->setFont(tmpFont); painter->setFont(tmpFont);
legendSize = calcChartLegendSize(tmpFont); legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0);
} }
painter->setFont(tmpFont); break;
legendRect = calcChartLegendRect(tmpFont, legendRect, true, 0, 0);
} }
} }
@ -723,28 +791,54 @@ int AbstractSeriesChart::seriesCount()
return m_chartItem->series().count(); return m_chartItem->series().count();
} }
QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font) QSizeF AbstractSeriesChart::calcChartLegendSize(const QFont &font, const qreal maxWidth)
{ {
QFontMetrics fm(font); QFontMetrics fm(font);
qreal cw = 0; switch(m_chartItem->legendAlign()) {
qreal maxWidth = 0; case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
if (!m_chartItem->series().isEmpty()){ case ChartItem::LegendAlignBottomRight: {
foreach(SeriesItem* series, m_chartItem->series()){ const qreal seriesCount = m_chartItem->series().isEmpty() ? m_designLabels.size() : m_chartItem->series().size();
cw += fm.height(); const qreal indicatorWidth = fm.height() * 1.5;
if (maxWidth<fm.boundingRect(series->name()).width()) m_legendColumnWidths.clear();
maxWidth = fm.boundingRect(series->name()).width()+10; while (!calculateLegendColumnWidths(indicatorWidth, maxWidth, fm)) {
// Nothing to do here
} }
} else { if (m_legendColumnWidths.isEmpty()) {
foreach(QString label, m_designLabels){ m_legendColumnWidths.append(0);
cw += fm.height();
if (maxWidth<fm.boundingRect(label).width())
maxWidth = fm.boundingRect(label).width()+10;
} }
const qreal columnCount = m_legendColumnWidths.size();
const qreal rowCount = std::ceil(seriesCount / columnCount);
QSizeF legendSize(std::accumulate(m_legendColumnWidths.cbegin(), m_legendColumnWidths.cend(), 0.0) + fm.height() / 2,
(rowCount + 1) * fm.height());
if (legendSize.width() > maxWidth) {
legendSize.setWidth(maxWidth);
}
return legendSize;
} }
cw += fm.height(); default: {
return QSizeF(maxWidth+fm.height()*2,cw); qreal cw = 0;
qreal maxWidth = 0;
if (m_chartItem->series().isEmpty()) {
foreach(QString label, m_designLabels){
cw += fm.height();
if (maxWidth<fm.boundingRect(label).width())
maxWidth = fm.boundingRect(label).width()+10;
}
} else {
foreach(SeriesItem* series, m_chartItem->series()){
cw += fm.height();
if (maxWidth<fm.boundingRect(series->name()).width())
maxWidth = fm.boundingRect(series->name()).width()+10;
}
}
cw += fm.height();
return QSizeF(maxWidth+fm.height()*2,cw);
}
}
return QSizeF();
} }
bool AbstractSeriesChart::verticalLabels(QPainter* painter, QRectF labelsRect) bool AbstractSeriesChart::verticalLabels(QPainter* painter, QRectF labelsRect)
@ -1028,48 +1122,108 @@ QString AbstractSeriesChart::axisLabel(int i, const AxisData &axisData)
return QString::number(round(value * 100.0) / 100.0); return QString::number(round(value * 100.0) / 100.0);
} }
bool AbstractSeriesChart::calculateLegendColumnWidths(qreal indicatorWidth, qreal maxWidth, const QFontMetrics &fm)
{
qreal currentRowWidth = 0;
int currentColumn = 0;
int maxColumnCount = m_legendColumnWidths.size();
if (m_chartItem->series().isEmpty()) {
for (int i=0 ; i < m_designLabels.size() ; ++i) {
const qreal itemWidth = (qreal)(fm.boundingRect(m_designLabels[i]).width()) + indicatorWidth;
if (!calculateLegendSingleColumnWidth(currentRowWidth, currentColumn, maxColumnCount, itemWidth, maxWidth)) {
return false;
}
}
} else {
for (int i = 0 ; i < m_chartItem->series().size() ; ++i) {
SeriesItem* series = m_chartItem->series().at(i);
const qreal itemWidth = (qreal)(fm.boundingRect(series->name()).width()) + indicatorWidth;
if (!calculateLegendSingleColumnWidth(currentRowWidth, currentColumn, maxColumnCount, itemWidth, maxWidth)) {
return false;
}
}
}
return true;
}
bool AbstractSeriesChart::calculateLegendSingleColumnWidth(qreal &currentRowWidth, int &currentColumn, int &maxColumnCount, const qreal itemWidth, const qreal maxWidth)
{
// TODO_ES optimise ?, it's hard to read
const bool isEnoughSpaceInRowForItem = currentRowWidth + itemWidth > maxWidth;
const bool lastColumnReached = (maxColumnCount > 0 && currentColumn >= maxColumnCount);
if (isEnoughSpaceInRowForItem || lastColumnReached) {
currentColumn = 0;
if (maxColumnCount == 0) {
maxColumnCount = currentColumn + 1;
}
currentRowWidth = itemWidth;
} else {
currentRowWidth += itemWidth;
}
if (currentColumn >= m_legendColumnWidths.size()) {
m_legendColumnWidths.append(itemWidth);
} else if (m_legendColumnWidths.at(currentColumn) < itemWidth) {
m_legendColumnWidths[currentColumn] = itemWidth;
qreal tmpWidth = itemWidth;
for (int c = 1 ; c < m_legendColumnWidths.size() ; c++) {
tmpWidth += m_legendColumnWidths.at(c);
if (tmpWidth > maxWidth) {
m_legendColumnWidths.remove(c, m_legendColumnWidths.size() - c);
break;
}
}
return false;
}
++currentColumn;
return true;
}
QVector<qreal> AbstractChart::legendColumnWidths() const
{
return m_legendColumnWidths;
}
void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect) void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect)
{ {
prepareLegendToPaint(legendRect, painter); prepareLegendToPaint(legendRect, painter);
int indicatorSize = painter->fontMetrics().height()/2;
painter->setPen(Qt::black); painter->setPen(Qt::black);
painter->setRenderHint(QPainter::Antialiasing,false); painter->setRenderHint(QPainter::Antialiasing,false);
if (m_chartItem->drawLegendBorder()) if (m_chartItem->drawLegendBorder())
painter->drawRect(legendRect); painter->drawRect(legendRect);
painter->setRenderHint(QPainter::Antialiasing,true); painter->setRenderHint(QPainter::Antialiasing,true);
QRectF indicatorsRect = legendRect.adjusted(painter->fontMetrics().height()/2,painter->fontMetrics().height()/2,0,0);
const qreal halfFontSize = painter->fontMetrics().height() / 2;
int indicatorSize = halfFontSize;
const QRectF indicatorsRect = legendRect.adjusted(halfFontSize, halfFontSize, 0, 0);
bool isHorizontal = false;
switch(m_chartItem->legendAlign()) {
case ChartItem::LegendAlignBottomLeft:
case ChartItem::LegendAlignBottomCenter:
case ChartItem::LegendAlignBottomRight:
isHorizontal = true;
break;
default:
isHorizontal = false;
break;
}
if (!m_chartItem->series().isEmpty()){ if (!m_chartItem->series().isEmpty()){
qreal cw = 0; for (int i = 0 ; i < m_chartItem->series().size() ; ++i) {
foreach(SeriesItem* series, m_chartItem->series()){ SeriesItem* series = m_chartItem->series().at(i);
QString label = series->name(); if (isHorizontal) {
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); drawHorizontalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
painter->setBrush(series->color()); } else {
painter->drawEllipse( drawVerticalLegendItem(painter, i, series->name(), indicatorSize, indicatorsRect, series->color());
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){ } else if (m_chartItem->itemMode() == DesignMode) {
qreal cw = 0; for (int i = 0 ; i < m_designLabels.size() ; ++i){
for (int i=0;i<m_designLabels.size();++i){ if (isHorizontal) {
QString label = m_designLabels.at(i); drawHorizontalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize/2,cw,0,0),label); } else {
painter->setBrush(color_map[i]); drawVerticalLegendItem(painter, i, m_designLabels.at(i), indicatorSize, indicatorsRect, color_map[i]);
painter->drawEllipse( }
indicatorsRect.adjusted(
0,
cw+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(cw+indicatorSize+indicatorSize/2))
)
);
cw += painter->fontMetrics().height();
} }
} }
@ -1105,4 +1259,66 @@ QRectF AbstractBarChart::horizontalLabelsRect(QPainter *painter, QRectF labelsRe
return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0); return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0);
} }
void AbstractBarChart::drawVerticalLegendItem(QPainter *painter, int i, const QString &text, int indicatorSize,
const QRectF &indicatorsRect, const QColor &indicatorColor)
{
const qreal y = i * painter->fontMetrics().height();
painter->drawText(indicatorsRect.adjusted(indicatorSize+indicatorSize * 1.5, y, 0, 0),text);
switch(m_chartItem->legendStyle()) {
case ChartItem::LegendPoints: {
painter->setBrush(indicatorColor);
painter->drawEllipse(
indicatorsRect.adjusted(
0,
y+indicatorSize/2,
-(indicatorsRect.width()-indicatorSize),
-(indicatorsRect.height()-(y+indicatorSize+indicatorSize/2))
)
);
break;
}
case ChartItem::LegendLines: {
const QPen tmpPen = painter->pen();
QPen indicatorPen(indicatorColor);
indicatorPen.setWidth(4);
painter->setPen(indicatorPen);
const QPointF linePos = QPointF(indicatorsRect.left(), indicatorsRect.top() + y + painter->fontMetrics().height()/2);
painter->drawLine(linePos, linePos + QPointF(indicatorSize, 0));
painter->setPen(tmpPen);
break;
}
}
}
void AbstractBarChart::drawHorizontalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor)
{
const QVector<qreal> &columnWidths = legendColumnWidths();
if (columnWidths.isEmpty())
return;
const int column = i % columnWidths.size();
const int row = std::floor(i / columnWidths.size());
const qreal halfTextSize = painter->fontMetrics().height() / 2;
const qreal x = indicatorsRect.x() + std::accumulate(columnWidths.cbegin(), columnWidths.cbegin() + column, 0.0);
const qreal y = indicatorsRect.y() + (row + 1) * painter->fontMetrics().height();
painter->drawText(QPointF(x + indicatorSize * 1.5, y), text);
switch(m_chartItem->legendStyle()) {
case ChartItem::LegendPoints: {
painter->setBrush(indicatorColor);
painter->drawEllipse(x, y - halfTextSize, indicatorSize, indicatorSize);
break;
}
case ChartItem::LegendLines: {
const QPen tmpPen = painter->pen();
QPen indicatorPen(indicatorColor);
indicatorPen.setWidth(4);
painter->setPen(indicatorPen);
painter->drawLine(x, y - halfTextSize * 0.7, x + indicatorSize, y - halfTextSize * 0.7);
painter->setPen(tmpPen);
break;
}
}
}
} // namespace LimeReport } // namespace LimeReport

View File

@ -76,12 +76,13 @@ public:
virtual ~AbstractChart(){} virtual ~AbstractChart(){}
virtual void paintChart(QPainter *painter, QRectF rect) = 0; virtual void paintChart(QPainter *painter, QRectF rect) = 0;
virtual void paintChartLegend(QPainter *painter, QRectF legendRect) =0; virtual void paintChartLegend(QPainter *painter, QRectF legendRect) =0;
virtual QSizeF calcChartLegendSize(const QFont &font) = 0; virtual QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth = 0) = 0;
virtual QRectF calcChartLegendRect(const QFont& font, const QRectF& parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset); virtual QRectF calcChartLegendRect(const QFont& font, const QRectF& parentRect, bool takeAllRect, qreal borderMargin, qreal titleOffset);
QFont titleFont(); QFont titleFont();
void setTitleFont(const QFont &value); void setTitleFont(const QFont &value);
protected: protected:
QVector<qreal> legendColumnWidths() const;
virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter); virtual void prepareLegendToPaint(QRectF& legendRect, QPainter *painter);
protected: protected:
// Title font must be placed here instead of CharItem, becuase // Title font must be placed here instead of CharItem, becuase
@ -89,6 +90,7 @@ protected:
QFont m_titleFont; QFont m_titleFont;
ChartItem* m_chartItem; ChartItem* m_chartItem;
QList<QString> m_designLabels; QList<QString> m_designLabels;
QVector<qreal> m_legendColumnWidths;
}; };
class AbstractSeriesChart: public AbstractChart{ class AbstractSeriesChart: public AbstractChart{
@ -103,7 +105,7 @@ protected:
int valuesCount(); int valuesCount();
int seriesCount(); int seriesCount();
bool verticalLabels(QPainter* painter, QRectF labelsRect); bool verticalLabels(QPainter* painter, QRectF labelsRect);
QSizeF calcChartLegendSize(const QFont &font); QSizeF calcChartLegendSize(const QFont &font, qreal maxWidth);
qreal* designValues(){ return m_designValues;} qreal* designValues(){ return m_designValues;}
virtual qreal hPadding(QRectF chartRect); virtual qreal hPadding(QRectF chartRect);
virtual qreal vPadding(QRectF chartRect); virtual qreal vPadding(QRectF chartRect);
@ -120,6 +122,9 @@ protected:
virtual QString axisLabel(int i, const AxisData &axisData); virtual QString axisLabel(int i, const AxisData &axisData);
private: private:
bool calculateLegendColumnWidths(qreal indicatorWidth, qreal maxWidth, const QFontMetrics &fm);
bool calculateLegendSingleColumnWidth(qreal &currentRowWidth, int &currentColumn, int &maxColumnCount,
const qreal itemWidth, const qreal maxWidth);
AxisData m_yAxisData, m_xAxisData; AxisData m_yAxisData, m_xAxisData;
qreal m_designValues [9]; qreal m_designValues [9];
}; };
@ -131,6 +136,11 @@ public:
protected: protected:
QRectF verticalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect); QRectF verticalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect);
virtual QRectF horizontalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect); virtual QRectF horizontalLabelsRect(QPainter* painter, QRectF horizontalLabelsRect);
private:
void drawVerticalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor);
void drawHorizontalLegendItem(QPainter *painter, int i, const QString &text,
int indicatorSize, const QRectF &indicatorsRect, const QColor &indicatorColor);
}; };
class ChartItem : public LimeReport::ItemDesignIntf class ChartItem : public LimeReport::ItemDesignIntf
@ -141,6 +151,7 @@ class ChartItem : public LimeReport::ItemDesignIntf
Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle) Q_PROPERTY(QString chartTitle READ chartTitle WRITE setChartTitle)
Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder) Q_PROPERTY(bool drawLegendBorder READ drawLegendBorder WRITE setDrawLegendBorder)
Q_PROPERTY(LegendAlign legendAlign READ legendAlign WRITE setLegendAlign) Q_PROPERTY(LegendAlign legendAlign READ legendAlign WRITE setLegendAlign)
Q_PROPERTY(LegendStyle legendStyle READ legendStyle WRITE setLegendStyle)
Q_PROPERTY(TitleAlign titleAlign READ titleAlign WRITE setTitleAlign) Q_PROPERTY(TitleAlign titleAlign READ titleAlign WRITE setTitleAlign)
Q_PROPERTY(ChartType chartType READ chartType WRITE setChartType) Q_PROPERTY(ChartType chartType READ chartType WRITE setChartType)
Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField) Q_PROPERTY(QString labelsField READ labelsField WRITE setLabelsField)
@ -160,7 +171,8 @@ class ChartItem : public LimeReport::ItemDesignIntf
friend class AbstractChart; friend class AbstractChart;
public: public:
enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom}; enum LegendAlign{LegendAlignRightTop,LegendAlignRightCenter,LegendAlignRightBottom,
LegendAlignBottomLeft,LegendAlignBottomCenter,LegendAlignBottomRight};
enum LegendStyle{LegendPoints, LegendLines}; enum LegendStyle{LegendPoints, LegendLines};
enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight}; enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight};
enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines}; enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines};
@ -172,11 +184,13 @@ public:
}; };
#if QT_VERSION >= 0x050500 #if QT_VERSION >= 0x050500
Q_ENUM(LegendAlign) Q_ENUM(LegendAlign)
Q_ENUM(LegendStyle)
Q_ENUM(TitleAlign) Q_ENUM(TitleAlign)
Q_ENUM(ChartType) Q_ENUM(ChartType)
Q_ENUM(LineType) Q_ENUM(LineType)
#else #else
Q_ENUMS(LegendAlign) Q_ENUMS(LegendAlign)
Q_ENUMS(LegendStyle)
Q_ENUMS(TitleAlign) Q_ENUMS(TitleAlign)
Q_ENUMS(ChartType) Q_ENUMS(ChartType)
Q_ENUMS(LineType) Q_ENUMS(LineType)
@ -203,6 +217,9 @@ public:
LegendAlign legendAlign() const; LegendAlign legendAlign() const;
void setLegendAlign(const LegendAlign &legendAlign); void setLegendAlign(const LegendAlign &legendAlign);
LegendStyle legendStyle() const;
void setLegendStyle(const LegendStyle &legendStyle);
TitleAlign titleAlign() const; TitleAlign titleAlign() const;
void setTitleAlign(const TitleAlign &titleAlign); void setTitleAlign(const TitleAlign &titleAlign);
@ -269,6 +286,7 @@ private:
QString m_xAxisField; QString m_xAxisField;
bool m_horizontalAxisOnTop; bool m_horizontalAxisOnTop;
GridChartLines m_gridChartLines; GridChartLines m_gridChartLines;
LegendStyle m_legendStyle;
}; };
} //namespace LimeReport } //namespace LimeReport
#endif // LRCHARTITEM_H #endif // LRCHARTITEM_H