mirror of
https://github.com/python-LimeReport/LimeReport.git
synced 2024-12-24 12:34:39 +03:00
Merge pull request #380 from emil-sawicki9/feature/charts-x-axis
Added grid chart with x axis
This commit is contained in:
commit
bc7666c351
112
limereport/items/charts/lrgridlineschart.cpp
Normal file
112
limereport/items/charts/lrgridlineschart.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include "lrgridlineschart.h"
|
||||||
|
|
||||||
|
namespace LimeReport {
|
||||||
|
void GridLinesChart::paintChart(QPainter *painter, QRectF chartRect)
|
||||||
|
{
|
||||||
|
updateMinAndMaxValues();
|
||||||
|
|
||||||
|
const qreal hPadding = this->hPadding(chartRect);
|
||||||
|
const qreal vPadding = this->vPadding(chartRect);
|
||||||
|
|
||||||
|
const qreal valuesVMargin = this->valuesVMargin(painter);
|
||||||
|
|
||||||
|
QRectF gridRect = chartRect.adjusted(
|
||||||
|
hPadding,
|
||||||
|
vPadding + valuesVMargin * 2,
|
||||||
|
-hPadding * 3,
|
||||||
|
-vPadding * 3
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!m_chartItem->horizontalAxisOnTop()) {
|
||||||
|
// If horizontal axis is on the bottom, move grid a little up
|
||||||
|
gridRect.adjust(0, -valuesVMargin, 0 , -valuesVMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapt font for horizontal axis
|
||||||
|
painter->setFont(adaptFont((gridRect.width() - this->valuesHMargin(painter)) / xAxisData().segmentCount() * 0.8,
|
||||||
|
painter->font(),
|
||||||
|
xAxisData()));
|
||||||
|
|
||||||
|
const qreal valuesHMargin = this->valuesHMargin(painter);
|
||||||
|
|
||||||
|
// Adjust vertical axis labels padding
|
||||||
|
gridRect.adjust(valuesHMargin * 0.2, 0, 0, 0);
|
||||||
|
|
||||||
|
paintGrid(painter, gridRect);
|
||||||
|
|
||||||
|
paintSerialLines(
|
||||||
|
painter,
|
||||||
|
gridRect.adjusted(hPadding + valuesHMargin, 0, 0, 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GridLinesChart::paintSerialLines(QPainter* painter, QRectF barsRect)
|
||||||
|
{
|
||||||
|
if (valuesCount() == 0) return;
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing,true);
|
||||||
|
|
||||||
|
const AxisData &yAxisData = this->yAxisData();
|
||||||
|
const qreal delta = yAxisData.delta();
|
||||||
|
|
||||||
|
if (m_chartItem->itemMode() == DesignMode){
|
||||||
|
const qreal hStep = barsRect.width() / valuesCount();
|
||||||
|
const qreal vStep = barsRect.height() / delta;
|
||||||
|
const qreal topShift = (delta - (maxValue() - minValue())) * vStep + barsRect.top();
|
||||||
|
drawDesignMode(painter, hStep, vStep, topShift, barsRect);
|
||||||
|
painter->restore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AxisData &xAxisData = this->xAxisData();
|
||||||
|
const qreal hStep = barsRect.width() / (xAxisData.rangeMax() - xAxisData.rangeMin());
|
||||||
|
|
||||||
|
qreal leftMargin = 0;
|
||||||
|
const qreal topMargin = barsRect.top();
|
||||||
|
|
||||||
|
for (SeriesItem* series : m_chartItem->series()) {
|
||||||
|
QPen pen(series->color());
|
||||||
|
pen.setWidth(m_chartItem->seriesLineWidth());
|
||||||
|
painter->setPen(pen);
|
||||||
|
|
||||||
|
const QList<qreal> &xAxisValues = series->data()->xAxisValues();
|
||||||
|
const QList<qreal> &values = series->data()->values();
|
||||||
|
const int xAxisValuesSize = xAxisValues.size();
|
||||||
|
qreal lastXPos = 0;
|
||||||
|
qreal lastYPos = 0;
|
||||||
|
if (!values.isEmpty()) {
|
||||||
|
// Calculate first point position on plot before loop
|
||||||
|
lastYPos = calculatePos(yAxisData, values.first(), barsRect.height());
|
||||||
|
}
|
||||||
|
if (xAxisValues.isEmpty()) {
|
||||||
|
leftMargin = barsRect.left();
|
||||||
|
} else {
|
||||||
|
leftMargin = barsRect.left();
|
||||||
|
lastXPos = calculatePos(xAxisData, xAxisValues.first(), barsRect.width());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < values.count() - 1; ++i ) {
|
||||||
|
const qreal startY = lastYPos;
|
||||||
|
const qreal endY = calculatePos(yAxisData, values.at(i+1), barsRect.height());
|
||||||
|
// Record last used Y position to only calculate new one
|
||||||
|
lastYPos = endY;
|
||||||
|
|
||||||
|
qreal startX = lastXPos;
|
||||||
|
qreal endX = 0;
|
||||||
|
if (i + 1 < xAxisValuesSize) {
|
||||||
|
endX = calculatePos(xAxisData, xAxisValues.at(i+1), barsRect.width());
|
||||||
|
} else {
|
||||||
|
endX = startX + hStep;
|
||||||
|
}
|
||||||
|
// Record last used X position to only calculate new one
|
||||||
|
lastXPos = endX;
|
||||||
|
|
||||||
|
QPoint startPoint = QPoint(startX + leftMargin, startY + topMargin);
|
||||||
|
QPoint endPoint = QPoint(endX + leftMargin, endY + topMargin);
|
||||||
|
drawSegment(painter, startPoint, endPoint, series->color());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
}
|
17
limereport/items/charts/lrgridlineschart.h
Normal file
17
limereport/items/charts/lrgridlineschart.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef GRIDLINESCHART_H
|
||||||
|
#define GRIDLINESCHART_H
|
||||||
|
|
||||||
|
#include "lrlineschart.h"
|
||||||
|
|
||||||
|
namespace LimeReport {
|
||||||
|
class GridLinesChart : public LinesChart{
|
||||||
|
public:
|
||||||
|
GridLinesChart(ChartItem* chartItem):LinesChart(chartItem){}
|
||||||
|
void paintChart(QPainter *painter, QRectF chartRect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paintSerialLines(QPainter *painter, QRectF barsRect);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GRIDLINESCHART_H
|
@ -20,7 +20,9 @@ void HorizontalBarChart::paintChart(QPainter *painter, QRectF chartRect)
|
|||||||
paintHorizontalGrid(painter, chartRect.adjusted(
|
paintHorizontalGrid(painter, chartRect.adjusted(
|
||||||
hPadding(chartRect) + barsShift,
|
hPadding(chartRect) + barsShift,
|
||||||
vPadding(chartRect),
|
vPadding(chartRect),
|
||||||
-(hPadding(chartRect)),-vPadding(chartRect)));
|
-(hPadding(chartRect)),
|
||||||
|
-vPadding(chartRect)));
|
||||||
|
|
||||||
paintHorizontalBars(painter, chartRect.adjusted(
|
paintHorizontalBars(painter, chartRect.adjusted(
|
||||||
hPadding(chartRect) + barsShift,
|
hPadding(chartRect) + barsShift,
|
||||||
vPadding(chartRect) * 2,
|
vPadding(chartRect) * 2,
|
||||||
@ -36,25 +38,33 @@ void HorizontalBarChart::paintHorizontalBars(QPainter *painter, QRectF barsRect)
|
|||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing,false);
|
painter->setRenderHint(QPainter::Antialiasing,false);
|
||||||
|
|
||||||
const AxisData &yAxisData = this->yAxisData();
|
const AxisData &yAxisData = this->yAxisData();
|
||||||
const qreal delta = yAxisData.delta();
|
const qreal delta = yAxisData.delta();
|
||||||
|
|
||||||
qreal vStep = (barsRect.height()-painter->fontMetrics().height()) / valuesCount() / seriesCount();
|
const qreal verticalOffset = painter->fontMetrics().height();
|
||||||
|
qreal vStep = (barsRect.height() - verticalOffset) / valuesCount() / seriesCount();
|
||||||
qreal hStep = (barsRect.width()-painter->fontMetrics().boundingRect(QString::number(maxValue())).width()) / delta;
|
qreal hStep = (barsRect.width()-painter->fontMetrics().boundingRect(QString::number(maxValue())).width()) / delta;
|
||||||
|
|
||||||
if (!m_chartItem->series().isEmpty() && (m_chartItem->itemMode() != DesignMode)){
|
if (!m_chartItem->series().isEmpty() && (m_chartItem->itemMode() != DesignMode)){
|
||||||
int curSeries = 0;
|
qreal curVOffset = barsRect.top();
|
||||||
|
if (m_chartItem->horizontalAxisOnTop()) {
|
||||||
|
curVOffset += verticalOffset;
|
||||||
|
}
|
||||||
foreach (SeriesItem* series, m_chartItem->series()) {
|
foreach (SeriesItem* series, m_chartItem->series()) {
|
||||||
qreal curVOffset = curSeries*vStep+barsRect.top();
|
|
||||||
painter->setBrush(series->color());
|
painter->setBrush(series->color());
|
||||||
|
qreal y = curVOffset;
|
||||||
foreach (qreal value, series->data()->values()) {
|
foreach (qreal value, series->data()->values()) {
|
||||||
painter->drawRect(QRectF((-minValue()*hStep)+barsRect.left(), curVOffset, value*hStep, vStep));
|
painter->drawRect(QRectF((-minValue()*hStep)+barsRect.left(), y, value*hStep, vStep));
|
||||||
curVOffset+=vStep*seriesCount();
|
y+=vStep*seriesCount();
|
||||||
}
|
}
|
||||||
curSeries++;
|
curVOffset += vStep;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qreal curVOffset = barsRect.top();
|
qreal curVOffset = barsRect.top();
|
||||||
|
if (m_chartItem->horizontalAxisOnTop()) {
|
||||||
|
curVOffset += verticalOffset;
|
||||||
|
}
|
||||||
int curColor = 0;
|
int curColor = 0;
|
||||||
for (int i=0; i<9; ++i){
|
for (int i=0; i<9; ++i){
|
||||||
if (curColor==3) curColor=0;
|
if (curColor==3) curColor=0;
|
||||||
|
@ -68,17 +68,18 @@ void LinesChart::drawDesignMode(QPainter* painter, qreal hStep, qreal vStep, qre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal LinesChart::calculateValueYPos(qreal, qreal max, qreal value, qreal delta, qreal height)
|
qreal LinesChart::calculatePos(const AxisData &data, qreal value, qreal rectSize) const
|
||||||
{
|
{
|
||||||
return (max - value) / delta * height;
|
return (data.rangeMax() - value) / data.delta() * rectSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect)
|
void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect)
|
||||||
{
|
{
|
||||||
const AxisData &yAxisData = this->yAxisData();
|
const AxisData &yAxisData = this->yAxisData();
|
||||||
const qreal delta = yAxisData.delta();
|
const AxisData &xAxisData = this->xAxisData();
|
||||||
|
|
||||||
const qreal hStep = barsRect.width() / valuesCount();
|
const qreal xAxisDiff = std::max(1.0, xAxisData.maxValue() - xAxisData.minValue());
|
||||||
|
const qreal hStep = barsRect.width() / xAxisDiff;
|
||||||
const qreal topMargin = barsRect.top();
|
const qreal topMargin = barsRect.top();
|
||||||
|
|
||||||
QPen pen(series->color());
|
QPen pen(series->color());
|
||||||
@ -91,11 +92,11 @@ void LinesChart::paintSeries(QPainter *painter, SeriesItem *series, QRectF barsR
|
|||||||
qreal lastXValue = barsRect.left() + hStep/2;
|
qreal lastXValue = barsRect.left() + hStep/2;
|
||||||
if (!values.isEmpty()) {
|
if (!values.isEmpty()) {
|
||||||
// Calculate first point position on plot before loop
|
// Calculate first point position on plot before loop
|
||||||
lastYValue = calculateValueYPos(yAxisData.rangeMin(), yAxisData.rangeMax(), values.first(), delta, barsRect.height());
|
lastYValue = calculatePos(yAxisData, values.first(), barsRect.height());
|
||||||
}
|
}
|
||||||
for (int i = 0; i < values.count()-1; ++i ){
|
for (int i = 0; i < values.count()-1; ++i ){
|
||||||
const qreal startY = lastYValue;
|
const qreal startY = lastYValue;
|
||||||
const qreal endY = calculateValueYPos(yAxisData.rangeMin(), yAxisData.rangeMax(), values.at(i+1), delta, barsRect.height());
|
const qreal endY = calculatePos(yAxisData, values.at(i+1), barsRect.height());
|
||||||
// Record last used Y position to only calculate new one
|
// Record last used Y position to only calculate new one
|
||||||
lastYValue = endY;
|
lastYValue = endY;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ public:
|
|||||||
void paintChart(QPainter *painter, QRectF chartRect);
|
void paintChart(QPainter *painter, QRectF chartRect);
|
||||||
protected:
|
protected:
|
||||||
void drawDesignMode(QPainter *painter, qreal hStep, qreal vStep, qreal topShift, QRectF barsRect);
|
void drawDesignMode(QPainter *painter, qreal hStep, qreal vStep, qreal topShift, QRectF barsRect);
|
||||||
qreal calculateValueYPos(qreal min, qreal max, qreal value, qreal delta, qreal height);
|
qreal calculatePos(const AxisData &data, qreal value, qreal rectSize) const;
|
||||||
void paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect);
|
void paintSeries(QPainter *painter, SeriesItem *series, QRectF barsRect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "charts/lrverticalbarchart.h"
|
#include "charts/lrverticalbarchart.h"
|
||||||
#include "charts/lrhorizontalbarchart.h"
|
#include "charts/lrhorizontalbarchart.h"
|
||||||
#include "charts/lrlineschart.h"
|
#include "charts/lrlineschart.h"
|
||||||
|
#include "charts/lrgridlineschart.h"
|
||||||
|
|
||||||
namespace{
|
namespace{
|
||||||
|
|
||||||
@ -79,6 +80,16 @@ void SeriesItem::setLabelsColumn(const QString &labelsColumn)
|
|||||||
m_labelsColumn = labelsColumn;
|
m_labelsColumn = labelsColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SeriesItem::xAxisColumn() const
|
||||||
|
{
|
||||||
|
return m_xAxisColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SeriesItem::setXAxisColumn(const QString &xAxisColumn)
|
||||||
|
{
|
||||||
|
m_xAxisColumn = xAxisColumn;
|
||||||
|
}
|
||||||
|
|
||||||
SeriesItem *SeriesItem::clone()
|
SeriesItem *SeriesItem::clone()
|
||||||
{
|
{
|
||||||
SeriesItem* result = new SeriesItem();
|
SeriesItem* result = new SeriesItem();
|
||||||
@ -98,6 +109,8 @@ void SeriesItem::fillSeriesData(IDataSource *dataSource)
|
|||||||
while(!dataSource->eof()){
|
while(!dataSource->eof()){
|
||||||
if (!m_labelsColumn.isEmpty())
|
if (!m_labelsColumn.isEmpty())
|
||||||
m_data.labels().append(dataSource->data(m_labelsColumn).toString());
|
m_data.labels().append(dataSource->data(m_labelsColumn).toString());
|
||||||
|
if (!m_xAxisColumn.isEmpty())
|
||||||
|
m_data.xAxisValues().append(dataSource->data(m_xAxisColumn).toDouble());
|
||||||
m_data.values().append(dataSource->data(m_valuesColumn).toDouble());
|
m_data.values().append(dataSource->data(m_valuesColumn).toDouble());
|
||||||
m_data.colors().append((currentColorIndex<32)?color_map[currentColorIndex]:generateColor());
|
m_data.colors().append((currentColorIndex<32)?color_map[currentColorIndex]:generateColor());
|
||||||
dataSource->next();
|
dataSource->next();
|
||||||
@ -130,7 +143,8 @@ 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(LegendAlignCenter), 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_labels<<"First"<<"Second"<<"Thrid";
|
m_labels<<"First"<<"Second"<<"Thrid";
|
||||||
m_chart = new PieChart(this);
|
m_chart = new PieChart(this);
|
||||||
@ -235,6 +249,7 @@ void ChartItem::updateItemSize(DataSourceManager *dataManager, RenderPass , int
|
|||||||
foreach (SeriesItem* series, m_series) {
|
foreach (SeriesItem* series, m_series) {
|
||||||
if (series->isEmpty()){
|
if (series->isEmpty()){
|
||||||
series->setLabelsColumn(m_labelsField);
|
series->setLabelsColumn(m_labelsField);
|
||||||
|
series->setXAxisColumn(m_xAxisField);
|
||||||
series->fillSeriesData(ds);
|
series->fillSeriesData(ds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,6 +342,10 @@ void ChartItem::setChartType(const ChartType &chartType)
|
|||||||
break;
|
break;
|
||||||
case Lines:
|
case Lines:
|
||||||
m_chart = new LinesChart(this);
|
m_chart = new LinesChart(this);
|
||||||
|
break;
|
||||||
|
case GridLines:
|
||||||
|
m_chart = new GridLinesChart(this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
notify("chartType",oldValue,m_chartType);
|
notify("chartType",oldValue,m_chartType);
|
||||||
update();
|
update();
|
||||||
@ -464,6 +483,50 @@ void ChartItem::setSeriesLineWidth(int newSeriesLineWidth)
|
|||||||
m_seriesLineWidth = newSeriesLineWidth;
|
m_seriesLineWidth = newSeriesLineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ChartItem::xAxisField() const
|
||||||
|
{
|
||||||
|
return m_xAxisField;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartItem::setXAxisField(const QString &xAxisField)
|
||||||
|
{
|
||||||
|
m_xAxisField = xAxisField;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChartItem::horizontalAxisOnTop() const
|
||||||
|
{
|
||||||
|
return m_horizontalAxisOnTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartItem::setHorizontalAxisOnTop(bool horizontalAxisOnTop)
|
||||||
|
{
|
||||||
|
if (m_horizontalAxisOnTop != horizontalAxisOnTop){
|
||||||
|
m_horizontalAxisOnTop = horizontalAxisOnTop;
|
||||||
|
notify("horizontalAxisOnTop", !m_horizontalAxisOnTop, m_horizontalAxisOnTop);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
m_horizontalAxisOnTop = horizontalAxisOnTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChartItem::GridChartLines ChartItem::gridChartLines() const
|
||||||
|
{
|
||||||
|
return m_gridChartLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartItem::setGridChartLines(GridChartLines flags)
|
||||||
|
{
|
||||||
|
if (m_gridChartLines == flags) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GridChartLines oldValue = m_gridChartLines;
|
||||||
|
m_gridChartLines = flags;
|
||||||
|
if (isLoading()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
update(rect());
|
||||||
|
notify("gridChartLines",QVariant(oldValue),QVariant(flags));
|
||||||
|
}
|
||||||
|
|
||||||
AbstractChart::AbstractChart(ChartItem *chartItem)
|
AbstractChart::AbstractChart(ChartItem *chartItem)
|
||||||
:m_chartItem(chartItem)
|
:m_chartItem(chartItem)
|
||||||
{
|
{
|
||||||
@ -552,22 +615,43 @@ AxisData AbstractSeriesChart::yAxisData()
|
|||||||
return m_yAxisData;
|
return m_yAxisData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AxisData AbstractSeriesChart::xAxisData()
|
||||||
|
{
|
||||||
|
return m_xAxisData;
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractSeriesChart::updateMinAndMaxValues()
|
void AbstractSeriesChart::updateMinAndMaxValues()
|
||||||
{
|
{
|
||||||
qreal maxYValue = 0;
|
qreal maxYValue = 0;
|
||||||
qreal minYValue = 0;
|
qreal minYValue = 0;
|
||||||
|
qreal maxXValue = 0;
|
||||||
|
qreal minXValue = 0;
|
||||||
if (m_chartItem->itemMode() == DesignMode) {
|
if (m_chartItem->itemMode() == DesignMode) {
|
||||||
maxYValue = 40;
|
maxYValue = 40;
|
||||||
|
maxXValue = 40;
|
||||||
} else {
|
} else {
|
||||||
for (SeriesItem* series : m_chartItem->series()){
|
for (SeriesItem* series : m_chartItem->series()){
|
||||||
for (qreal value : series->data()->values()){
|
for (qreal value : series->data()->values()){
|
||||||
minYValue = std::min(minYValue, value);
|
minYValue = std::min(minYValue, value);
|
||||||
maxYValue = std::max(maxYValue, value);
|
maxYValue = std::max(maxYValue, value);
|
||||||
}
|
}
|
||||||
|
if (series->data()->xAxisValues().isEmpty()) {
|
||||||
|
// Grid plot starts from 0 on x axis so x range must be decresed by 1
|
||||||
|
const bool startingFromZero = m_chartItem->chartType() == ChartItem::GridLines;
|
||||||
|
const qreal valuesCount = this->valuesCount() - (startingFromZero ? 1 : 0);
|
||||||
|
minXValue = std::min(0.0, minXValue);
|
||||||
|
maxXValue = std::max(valuesCount, maxXValue);
|
||||||
|
} else {
|
||||||
|
for (qreal value : series->data()->xAxisValues()){
|
||||||
|
minXValue = std::min(value, minXValue);
|
||||||
|
maxXValue = std::max(value, maxXValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_yAxisData = AxisData(minYValue, maxYValue);
|
m_yAxisData = AxisData(minYValue, maxYValue);
|
||||||
|
m_xAxisData = AxisData(minXValue, maxXValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal AbstractSeriesChart::hPadding(QRectF chartRect)
|
qreal AbstractSeriesChart::hPadding(QRectF chartRect)
|
||||||
@ -686,7 +770,6 @@ void AbstractSeriesChart::paintHorizontalGrid(QPainter *painter, QRectF gridRect
|
|||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
const AxisData &yAxisData = this->yAxisData();
|
const AxisData &yAxisData = this->yAxisData();
|
||||||
const qreal delta = yAxisData.delta();
|
|
||||||
|
|
||||||
const int segmentCount = yAxisData.segmentCount();
|
const int segmentCount = yAxisData.segmentCount();
|
||||||
const int lineCount = segmentCount + 1;
|
const int lineCount = segmentCount + 1;
|
||||||
@ -694,15 +777,20 @@ void AbstractSeriesChart::paintHorizontalGrid(QPainter *painter, QRectF gridRect
|
|||||||
painter->setRenderHint(QPainter::Antialiasing,false);
|
painter->setRenderHint(QPainter::Antialiasing,false);
|
||||||
qreal hStep = (gridRect.width() - painter->fontMetrics().boundingRect(QString::number(maxValue())).width()) / segmentCount;
|
qreal hStep = (gridRect.width() - painter->fontMetrics().boundingRect(QString::number(maxValue())).width()) / segmentCount;
|
||||||
|
|
||||||
painter->setFont(adaptValuesFont(hStep-4, painter->font()));
|
painter->setFont(adaptFont(hStep-4, painter->font(), yAxisData));
|
||||||
|
|
||||||
|
QPointF textPos;
|
||||||
|
if (m_chartItem->horizontalAxisOnTop()) {
|
||||||
|
textPos.setY(gridRect.top());
|
||||||
|
} else {
|
||||||
|
textPos.setY(gridRect.bottom() - painter->fontMetrics().height());
|
||||||
|
}
|
||||||
for (int i = 0 ; i < lineCount ; i++ ) {
|
for (int i = 0 ; i < lineCount ; i++ ) {
|
||||||
painter->drawText(QRectF(gridRect.left() + 4 + hStep * i, gridRect.bottom() - painter->fontMetrics().height(),
|
const qreal x = gridRect.left() + hStep * i;
|
||||||
hStep, painter->fontMetrics().height()),
|
textPos.setX(x + 4);
|
||||||
QString::number(minValue() + i * delta / segmentCount));
|
painter->drawText(QRectF(textPos, QSizeF(hStep, painter->fontMetrics().height())),
|
||||||
painter->drawLine( gridRect.left()+hStep*i, gridRect.bottom(),
|
axisLabel(i, yAxisData));
|
||||||
gridRect.left()+hStep*i, gridRect.top());
|
painter->drawLine(x, gridRect.bottom(), x, gridRect.top());
|
||||||
|
|
||||||
}
|
}
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
@ -727,7 +815,7 @@ void AbstractSeriesChart::paintVerticalGrid(QPainter *painter, QRectF gridRect)
|
|||||||
const qreal y = vStep * i;
|
const qreal y = vStep * i;
|
||||||
painter->drawText(QRectF(gridRect.bottomLeft()-QPointF(textPositionOffset,y+halfFontHeight),
|
painter->drawText(QRectF(gridRect.bottomLeft()-QPointF(textPositionOffset,y+halfFontHeight),
|
||||||
QSizeF(valuesHMargin,fontHeight)),
|
QSizeF(valuesHMargin,fontHeight)),
|
||||||
verticalLabel(i, yAxisData.step(), yAxisData.rangeMin()),
|
axisLabel(i, yAxisData),
|
||||||
verticalTextOption);
|
verticalTextOption);
|
||||||
painter->drawLine(gridRect.bottomLeft()-QPointF(-valuesHMargin,y),
|
painter->drawLine(gridRect.bottomLeft()-QPointF(-valuesHMargin,y),
|
||||||
gridRect.bottomRight()-QPointF(0,y));
|
gridRect.bottomRight()-QPointF(0,y));
|
||||||
@ -736,6 +824,73 @@ void AbstractSeriesChart::paintVerticalGrid(QPainter *painter, QRectF gridRect)
|
|||||||
painter->setRenderHint(QPainter::Antialiasing,true);
|
painter->setRenderHint(QPainter::Antialiasing,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractSeriesChart::paintGrid(QPainter *painter, QRectF gridRect)
|
||||||
|
{
|
||||||
|
painter->save();
|
||||||
|
|
||||||
|
const AxisData &yAxisData = this->yAxisData();
|
||||||
|
const AxisData &xAxisData = this->xAxisData();
|
||||||
|
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing,false);
|
||||||
|
|
||||||
|
const int xAxisSegmentCount = xAxisData.segmentCount();
|
||||||
|
const int xAxisLineCount = xAxisSegmentCount + 1;
|
||||||
|
const int yAxisSegmentCount = yAxisData.segmentCount();
|
||||||
|
const int yAxisLineCount = yAxisSegmentCount + 1;
|
||||||
|
|
||||||
|
const int fontHeight = painter->fontMetrics().height();
|
||||||
|
const int halfFontHeight = fontHeight / 2;
|
||||||
|
const QSizeF gridOffset = QSizeF(hPadding(gridRect), vPadding(gridRect));
|
||||||
|
const qreal valuesHMargin = this->valuesHMargin(painter);
|
||||||
|
const qreal vStep = gridRect.height() / yAxisSegmentCount;
|
||||||
|
const qreal hStep = (gridRect.width() - valuesHMargin - gridOffset.width()) / xAxisSegmentCount;
|
||||||
|
const qreal textPositionHOffset = valuesHMargin * 0.1;
|
||||||
|
|
||||||
|
// Vertical axis lines
|
||||||
|
const QTextOption verticalTextOption(Qt::AlignRight);
|
||||||
|
for (int i = 0 ; i < yAxisLineCount ; i++ ) {
|
||||||
|
const qreal y = vStep * i;
|
||||||
|
const bool drawFullLine = m_chartItem->gridChartLines() & ChartItem::HorizontalLine
|
||||||
|
|| i == 0 || i == xAxisSegmentCount;
|
||||||
|
painter->drawText(QRectF(gridRect.bottomLeft()-QPointF(textPositionHOffset, y + halfFontHeight),
|
||||||
|
QSizeF(valuesHMargin,fontHeight)),
|
||||||
|
axisLabel(i, yAxisData),
|
||||||
|
verticalTextOption);
|
||||||
|
|
||||||
|
QPointF lineEndPos = gridRect.bottomRight() - QPointF(0, y);
|
||||||
|
if (!drawFullLine) {
|
||||||
|
lineEndPos.setX(gridRect.left() + valuesHMargin + gridOffset.width());
|
||||||
|
}
|
||||||
|
painter->drawLine(gridRect.bottomLeft() - QPointF(-valuesHMargin, y), lineEndPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal axis lines
|
||||||
|
for (int i = 0 ; i < xAxisLineCount ; i++) {
|
||||||
|
const qreal x = gridRect.left() + hStep * i + valuesHMargin + gridOffset.width();
|
||||||
|
const bool drawFullLine = m_chartItem->gridChartLines() & ChartItem::VerticalLine
|
||||||
|
|| i == 0 || i == xAxisSegmentCount;
|
||||||
|
const QString text = axisLabel(i, xAxisData);
|
||||||
|
|
||||||
|
if (m_chartItem->horizontalAxisOnTop()) {
|
||||||
|
painter->drawLine(x, gridRect.top() - gridOffset.height(),
|
||||||
|
x, (drawFullLine ? gridRect.bottom() : gridRect.top()));
|
||||||
|
painter->drawText(QRectF(x - painter->fontMetrics().width(text) / 2,
|
||||||
|
gridRect.top() - (fontHeight + gridOffset.height()),
|
||||||
|
hStep, fontHeight),
|
||||||
|
text);
|
||||||
|
} else {
|
||||||
|
painter->drawLine(x, gridRect.bottom() + gridOffset.height(),
|
||||||
|
x, (drawFullLine ? gridRect.top() : gridRect.bottom()));
|
||||||
|
painter->drawText(QRectF(x - painter->fontMetrics().width(text) / 2,
|
||||||
|
gridRect.bottom() + halfFontHeight * 0 + gridOffset.height(),
|
||||||
|
hStep, fontHeight),
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractSeriesChart::drawSegment(QPainter *painter, QPoint startPoint, QPoint endPoint, QColor color)
|
void AbstractSeriesChart::drawSegment(QPainter *painter, QPoint startPoint, QPoint endPoint, QColor color)
|
||||||
{
|
{
|
||||||
int radius = m_chartItem->seriesLineWidth();
|
int radius = m_chartItem->seriesLineWidth();
|
||||||
@ -761,7 +916,7 @@ qreal AbstractSeriesChart::valuesHMargin(QPainter *painter)
|
|||||||
const int yAxisLineCount = yAxisData.segmentCount() + 1;
|
const int yAxisLineCount = yAxisData.segmentCount() + 1;
|
||||||
|
|
||||||
for (int i = 0 ; i < yAxisLineCount ; i++) {
|
for (int i = 0 ; i < yAxisLineCount ; i++) {
|
||||||
const QString label = verticalLabel(i, yAxisData.step(), yAxisData.rangeMin());
|
const QString label = axisLabel(i, yAxisData);
|
||||||
max = std::max(max, (qreal)painter->fontMetrics().boundingRect(label).width()+offset);
|
max = std::max(max, (qreal)painter->fontMetrics().boundingRect(label).width()+offset);
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
@ -797,28 +952,33 @@ QFont AbstractSeriesChart::adaptLabelsFont(QRectF rect, QFont font)
|
|||||||
return tmpFont;
|
return tmpFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFont AbstractSeriesChart::adaptValuesFont(qreal width, QFont font)
|
QFont AbstractSeriesChart::adaptFont(qreal width, QFont font, const AxisData &axisData)
|
||||||
{
|
{
|
||||||
QString strValue = QString::number(maxValue());
|
|
||||||
QFont tmpFont = font;
|
QFont tmpFont = font;
|
||||||
|
const int axisLineCount = axisData.segmentCount() + 1;
|
||||||
QScopedPointer<QFontMetricsF> fm(new QFontMetricsF(tmpFont));
|
QScopedPointer<QFontMetricsF> fm(new QFontMetricsF(tmpFont));
|
||||||
qreal curWidth = fm->boundingRect(strValue).width();
|
for (int i = 0 ; i < axisLineCount ; i++) {
|
||||||
while (curWidth > width && tmpFont.pixelSize() > 1){
|
QString strValue = axisLabel(i, axisData);
|
||||||
tmpFont.setPixelSize(tmpFont.pixelSize() - 1);
|
qreal curWidth = fm->boundingRect(strValue).width();
|
||||||
fm.reset(new QFontMetricsF(tmpFont));
|
while (curWidth > width && tmpFont.pixelSize() > 1){
|
||||||
curWidth = fm->boundingRect(strValue).width();
|
tmpFont.setPixelSize(tmpFont.pixelSize() - 1);
|
||||||
|
fm.reset(new QFontMetricsF(tmpFont));
|
||||||
|
curWidth = fm->boundingRect(strValue).width();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tmpFont;
|
return tmpFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractSeriesChart::verticalLabel(int i, qreal step, qreal min)
|
QString AbstractSeriesChart::axisLabel(int i, const AxisData &axisData)
|
||||||
{
|
{
|
||||||
|
const qreal min = axisData.rangeMin();
|
||||||
|
const qreal step = axisData.step();
|
||||||
qreal value = min + i * step;
|
qreal value = min + i * step;
|
||||||
if (std::floor(step) == step) {
|
if (std::floor(step) == step) {
|
||||||
return QString::number(value);
|
return QString::number(value);
|
||||||
}
|
}
|
||||||
// For float round numbers to small precision
|
// For float round numbers to small precision
|
||||||
return QString::number(value, 'g', 2);
|
return QString::number(round(value * 100.0) / 100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect)
|
void AbstractBarChart::paintChartLegend(QPainter *painter, QRectF legendRect)
|
||||||
@ -897,4 +1057,5 @@ QRectF AbstractBarChart::horizontalLabelsRect(QPainter *painter, QRectF labelsRe
|
|||||||
else
|
else
|
||||||
return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0);
|
return labelsRect.adjusted(0, (labelsRect.height() - maxWidth), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LimeReport
|
} // namespace LimeReport
|
||||||
|
@ -16,11 +16,12 @@ class SeriesItemData : public QObject{
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
QList<qreal>& values(){ return m_values;}
|
QList<qreal>& values(){ return m_values;}
|
||||||
|
QList<qreal>& xAxisValues(){ return m_xAxisValues;}
|
||||||
QList<QString>& labels(){ return m_labels;}
|
QList<QString>& labels(){ return m_labels;}
|
||||||
QList<QColor>& colors() { return m_colors;}
|
QList<QColor>& colors() { return m_colors;}
|
||||||
void clear(){ m_values.clear(); m_labels.clear(); m_colors.clear(); }
|
void clear(){ m_values.clear(); m_labels.clear(); m_colors.clear(); }
|
||||||
private:
|
private:
|
||||||
QList<qreal> m_values;
|
QList<qreal> m_values, m_xAxisValues;
|
||||||
QList<QString> m_labels;
|
QList<QString> m_labels;
|
||||||
QList<QColor> m_colors;
|
QList<QColor> m_colors;
|
||||||
};
|
};
|
||||||
@ -30,6 +31,7 @@ class SeriesItem : public QObject{
|
|||||||
Q_PROPERTY(QString name READ name WRITE setName)
|
Q_PROPERTY(QString name READ name WRITE setName)
|
||||||
Q_PROPERTY(QString valuesColumn READ valuesColumn WRITE setValuesColumn)
|
Q_PROPERTY(QString valuesColumn READ valuesColumn WRITE setValuesColumn)
|
||||||
Q_PROPERTY(QString labelsColumn READ labelsColumn WRITE setLabelsColumn)
|
Q_PROPERTY(QString labelsColumn READ labelsColumn WRITE setLabelsColumn)
|
||||||
|
Q_PROPERTY(QString xAxisColumn READ xAxisColumn WRITE setXAxisColumn)
|
||||||
Q_PROPERTY(QColor color READ color WRITE setColor)
|
Q_PROPERTY(QColor color READ color WRITE setColor)
|
||||||
Q_PROPERTY(SeriesItemPreferredType preferredType READ preferredType WRITE setPreferredType)
|
Q_PROPERTY(SeriesItemPreferredType preferredType READ preferredType WRITE setPreferredType)
|
||||||
public:
|
public:
|
||||||
@ -46,6 +48,8 @@ public:
|
|||||||
void setValuesColumn(const QString &valuesColumn);
|
void setValuesColumn(const QString &valuesColumn);
|
||||||
QString labelsColumn() const;
|
QString labelsColumn() const;
|
||||||
void setLabelsColumn(const QString &labelsColumn);
|
void setLabelsColumn(const QString &labelsColumn);
|
||||||
|
QString xAxisColumn() const;
|
||||||
|
void setXAxisColumn(const QString &xAxisColumn);
|
||||||
SeriesItem* clone();
|
SeriesItem* clone();
|
||||||
void fillSeriesData(IDataSource* dataSource);
|
void fillSeriesData(IDataSource* dataSource);
|
||||||
SeriesItemData* data(){ return &m_data;}
|
SeriesItemData* data(){ return &m_data;}
|
||||||
@ -58,6 +62,7 @@ private:
|
|||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_valuesColumn;
|
QString m_valuesColumn;
|
||||||
QString m_labelsColumn;
|
QString m_labelsColumn;
|
||||||
|
QString m_xAxisColumn;
|
||||||
SeriesItemData m_data;
|
SeriesItemData m_data;
|
||||||
QColor m_color;
|
QColor m_color;
|
||||||
SeriesItemPreferredType m_preferredType;
|
SeriesItemPreferredType m_preferredType;
|
||||||
@ -84,9 +89,10 @@ class AbstractSeriesChart: public AbstractChart{
|
|||||||
public:
|
public:
|
||||||
AbstractSeriesChart(ChartItem* chartItem);
|
AbstractSeriesChart(ChartItem* chartItem);
|
||||||
protected:
|
protected:
|
||||||
|
AxisData yAxisData();
|
||||||
|
AxisData xAxisData();
|
||||||
qreal maxValue();
|
qreal maxValue();
|
||||||
qreal minValue();
|
qreal minValue();
|
||||||
AxisData yAxisData();
|
|
||||||
void updateMinAndMaxValues();
|
void updateMinAndMaxValues();
|
||||||
int valuesCount();
|
int valuesCount();
|
||||||
int seriesCount();
|
int seriesCount();
|
||||||
@ -98,16 +104,17 @@ protected:
|
|||||||
virtual void paintHorizontalLabels(QPainter *painter, QRectF labelsRect);
|
virtual void paintHorizontalLabels(QPainter *painter, QRectF labelsRect);
|
||||||
virtual void paintVerticalLabels(QPainter *painter, QRectF labelsRect);
|
virtual void paintVerticalLabels(QPainter *painter, QRectF labelsRect);
|
||||||
virtual void paintHorizontalGrid(QPainter *painter, QRectF gridRect);
|
virtual void paintHorizontalGrid(QPainter *painter, QRectF gridRect);
|
||||||
|
virtual void paintGrid(QPainter *painter, QRectF gridRect);
|
||||||
virtual void paintVerticalGrid(QPainter *painter, QRectF gridRect);
|
virtual void paintVerticalGrid(QPainter *painter, QRectF gridRect);
|
||||||
virtual void drawSegment(QPainter *painter, QPoint startPoint, QPoint endPoint, QColor color);
|
virtual void drawSegment(QPainter *painter, QPoint startPoint, QPoint endPoint, QColor color);
|
||||||
virtual qreal valuesHMargin(QPainter *painter);
|
virtual qreal valuesHMargin(QPainter *painter);
|
||||||
virtual qreal valuesVMargin(QPainter *painter);
|
virtual qreal valuesVMargin(QPainter *painter);
|
||||||
virtual QFont adaptLabelsFont(QRectF rect, QFont font);
|
virtual QFont adaptLabelsFont(QRectF rect, QFont font);
|
||||||
virtual QFont adaptValuesFont(qreal width, QFont font);
|
virtual QFont adaptFont(qreal width, QFont font, const AxisData &axisData);
|
||||||
virtual QString verticalLabel(int i, qreal step, qreal min);
|
virtual QString axisLabel(int i, const AxisData &axisData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AxisData m_yAxisData;
|
AxisData m_yAxisData, m_xAxisData;
|
||||||
qreal m_designValues [9];
|
qreal m_designValues [9];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,21 +143,37 @@ class ChartItem : public LimeReport::ItemDesignIntf
|
|||||||
//linesChart
|
//linesChart
|
||||||
Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints)
|
Q_PROPERTY(bool drawPoints READ drawPoints WRITE setDrawPoints)
|
||||||
Q_PROPERTY(int seriesLineWidth READ seriesLineWidth WRITE setSeriesLineWidth)
|
Q_PROPERTY(int seriesLineWidth READ seriesLineWidth WRITE setSeriesLineWidth)
|
||||||
|
Q_PROPERTY(bool horizontalAxisOnTop READ horizontalAxisOnTop WRITE setHorizontalAxisOnTop)
|
||||||
|
|
||||||
|
//gridChart
|
||||||
|
Q_FLAGS(GridChartLines)
|
||||||
|
Q_PROPERTY(QString xAxisField READ xAxisField WRITE setXAxisField)
|
||||||
|
Q_PROPERTY(GridChartLines gridChartLines READ gridChartLines WRITE setGridChartLines)
|
||||||
friend class AbstractChart;
|
friend class AbstractChart;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom};
|
enum LegendAlign{LegendAlignTop,LegendAlignCenter,LegendAlignBottom};
|
||||||
|
enum LegendStyle{LegendPoints, LegendLines};
|
||||||
enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight};
|
enum TitleAlign{TitleAlignLeft, TitleAlignCenter, TitleAlignRight};
|
||||||
enum ChartType{Pie, VerticalBar, HorizontalBar, Lines};
|
enum ChartType{Pie, VerticalBar, HorizontalBar, Lines, GridLines};
|
||||||
|
enum LineType {
|
||||||
|
NoLine = 0,
|
||||||
|
HorizontalLine = 1,
|
||||||
|
VerticalLine = 2,
|
||||||
|
AllLines = 3
|
||||||
|
};
|
||||||
#if QT_VERSION >= 0x050500
|
#if QT_VERSION >= 0x050500
|
||||||
Q_ENUM(LegendAlign)
|
Q_ENUM(LegendAlign)
|
||||||
Q_ENUM(TitleAlign)
|
Q_ENUM(TitleAlign)
|
||||||
Q_ENUM(ChartType)
|
Q_ENUM(ChartType)
|
||||||
|
Q_ENUM(LineType)
|
||||||
#else
|
#else
|
||||||
Q_ENUMS(LegendAlign)
|
Q_ENUMS(LegendAlign)
|
||||||
Q_ENUMS(TitleAlign)
|
Q_ENUMS(TitleAlign)
|
||||||
Q_ENUMS(ChartType)
|
Q_ENUMS(ChartType)
|
||||||
|
Q_ENUMS(LineType)
|
||||||
#endif
|
#endif
|
||||||
|
Q_DECLARE_FLAGS(GridChartLines, LineType)
|
||||||
|
|
||||||
ChartItem(QObject* owner, QGraphicsItem* parent);
|
ChartItem(QObject* owner, QGraphicsItem* parent);
|
||||||
~ChartItem();
|
~ChartItem();
|
||||||
@ -194,6 +217,15 @@ public:
|
|||||||
int seriesLineWidth() const;
|
int seriesLineWidth() const;
|
||||||
void setSeriesLineWidth(int newSeriesLineWidth);
|
void setSeriesLineWidth(int newSeriesLineWidth);
|
||||||
|
|
||||||
|
QString xAxisField() const;
|
||||||
|
void setXAxisField(const QString &xAxisField);
|
||||||
|
|
||||||
|
bool horizontalAxisOnTop() const;
|
||||||
|
void setHorizontalAxisOnTop(bool horizontalAxisOnTop);
|
||||||
|
|
||||||
|
GridChartLines gridChartLines() const;
|
||||||
|
void setGridChartLines(GridChartLines flags);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintChartTitle(QPainter* painter, QRectF titleRect);
|
void paintChartTitle(QPainter* painter, QRectF titleRect);
|
||||||
virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent);
|
virtual BaseDesignIntf* createSameTypeItem(QObject *owner, QGraphicsItem *parent);
|
||||||
@ -222,6 +254,9 @@ private:
|
|||||||
bool m_showLegend;
|
bool m_showLegend;
|
||||||
bool m_drawPoints;
|
bool m_drawPoints;
|
||||||
int m_seriesLineWidth;
|
int m_seriesLineWidth;
|
||||||
|
QString m_xAxisField;
|
||||||
|
bool m_horizontalAxisOnTop;
|
||||||
|
GridChartLines m_gridChartLines;
|
||||||
};
|
};
|
||||||
} //namespace LimeReport
|
} //namespace LimeReport
|
||||||
#endif // LRCHARTITEM_H
|
#endif // LRCHARTITEM_H
|
||||||
|
@ -106,6 +106,7 @@ void ChartItemEditor::init()
|
|||||||
for (int i=0;i<ds->columnCount();++i){
|
for (int i=0;i<ds->columnCount();++i){
|
||||||
ui->valuesFieldComboBox->addItem(ds->columnNameByIndex(i));
|
ui->valuesFieldComboBox->addItem(ds->columnNameByIndex(i));
|
||||||
ui->labelsFieldComboBox->addItem(ds->columnNameByIndex(i));
|
ui->labelsFieldComboBox->addItem(ds->columnNameByIndex(i));
|
||||||
|
ui->xAxisFieldComboBox->addItem(ds->columnNameByIndex(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,8 +121,10 @@ void ChartItemEditor::init()
|
|||||||
|
|
||||||
#if QT_VERSION < 0x050000
|
#if QT_VERSION < 0x050000
|
||||||
ui->labelsFieldComboBox->setCurrentIndex(ui->labelsFieldComboBox->findText( m_charItem->labelsField()));
|
ui->labelsFieldComboBox->setCurrentIndex(ui->labelsFieldComboBox->findText( m_charItem->labelsField()));
|
||||||
|
ui->xAxisFieldComboBox->setCurrentIndex(ui->xAxisFieldComboBox->findText( m_charItem->xAxisField()));
|
||||||
#else
|
#else
|
||||||
ui->labelsFieldComboBox->setCurrentText(m_charItem->labelsField());
|
ui->labelsFieldComboBox->setCurrentText(m_charItem->labelsField());
|
||||||
|
ui->xAxisFieldComboBox->setCurrentText(m_charItem->xAxisField());
|
||||||
#endif
|
#endif
|
||||||
if (!m_charItem->series().isEmpty()){
|
if (!m_charItem->series().isEmpty()){
|
||||||
enableSeriesEditor();
|
enableSeriesEditor();
|
||||||
@ -287,3 +290,9 @@ void ChartItemEditor::on_seriesTypeComboBox_currentIndexChanged(const QString &a
|
|||||||
currentSeries()->setPreferredType(static_cast<LimeReport::SeriesItem::SeriesItemPreferredType>(enumerator.keysToValue(arg1.toLatin1())));
|
currentSeries()->setPreferredType(static_cast<LimeReport::SeriesItem::SeriesItemPreferredType>(enumerator.keysToValue(arg1.toLatin1())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChartItemEditor::on_xAxisFieldComboBox_currentTextChanged(const QString &arg1)
|
||||||
|
{
|
||||||
|
if (!m_initing)
|
||||||
|
m_charItem->setXAxisField(arg1);
|
||||||
|
}
|
@ -41,6 +41,8 @@ private slots:
|
|||||||
void slotChangeSeriesColor();
|
void slotChangeSeriesColor();
|
||||||
void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1);
|
void on_seriesTypeComboBox_currentIndexChanged(const QString &arg1);
|
||||||
|
|
||||||
|
void on_xAxisFieldComboBox_currentTextChanged(const QString &arg1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void readSetting();
|
void readSetting();
|
||||||
void writeSetting();
|
void writeSetting();
|
||||||
|
@ -144,16 +144,30 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="labelsFieldComboBox">
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="labelsFieldLabel">
|
<widget class="QLabel" name="labelsFieldLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Labels field</string>
|
<string>Labels field</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<widget class="QComboBox" name="labelsFieldComboBox">
|
<widget class="QLabel" name="xAxisFieldLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>X data field</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="xAxisFieldComboBox">
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -49,6 +49,7 @@ SOURCES += \
|
|||||||
$$REPORT_PATH/items/lrchartitemeditor.cpp \
|
$$REPORT_PATH/items/lrchartitemeditor.cpp \
|
||||||
$$REPORT_PATH/items/charts/lrhorizontalbarchart.cpp \
|
$$REPORT_PATH/items/charts/lrhorizontalbarchart.cpp \
|
||||||
$$REPORT_PATH/items/charts/lrlineschart.cpp \
|
$$REPORT_PATH/items/charts/lrlineschart.cpp \
|
||||||
|
$$REPORT_PATH/items/charts/lrgridlineschart.cpp \
|
||||||
$$REPORT_PATH/items/charts/lrpiechart.cpp \
|
$$REPORT_PATH/items/charts/lrpiechart.cpp \
|
||||||
$$REPORT_PATH/items/charts/lrverticalbarchart.cpp \
|
$$REPORT_PATH/items/charts/lrverticalbarchart.cpp \
|
||||||
$$REPORT_PATH/lrbanddesignintf.cpp \
|
$$REPORT_PATH/lrbanddesignintf.cpp \
|
||||||
@ -132,6 +133,7 @@ HEADERS += \
|
|||||||
$$REPORT_PATH/items/lrchartitemeditor.h \
|
$$REPORT_PATH/items/lrchartitemeditor.h \
|
||||||
$$REPORT_PATH/items/charts/lrhorizontalbarchart.h \
|
$$REPORT_PATH/items/charts/lrhorizontalbarchart.h \
|
||||||
$$REPORT_PATH/items/charts/lrlineschart.h \
|
$$REPORT_PATH/items/charts/lrlineschart.h \
|
||||||
|
$$REPORT_PATH/items/charts/lrgridlineschart.h \
|
||||||
$$REPORT_PATH/items/charts/lrpiechart.h \
|
$$REPORT_PATH/items/charts/lrpiechart.h \
|
||||||
$$REPORT_PATH/items/charts/lrverticalbarchart.h \
|
$$REPORT_PATH/items/charts/lrverticalbarchart.h \
|
||||||
$$REPORT_PATH/lrbanddesignintf.h \
|
$$REPORT_PATH/lrbanddesignintf.h \
|
||||||
|
@ -20,9 +20,9 @@ public:
|
|||||||
qreal step() const;
|
qreal step() const;
|
||||||
|
|
||||||
qreal delta() const;
|
qreal delta() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void calculateValuesAboveMax(qreal minValue, qreal maxValue, int segments);
|
void calculateValuesAboveMax(qreal minValue, qreal maxValue, int segments);
|
||||||
qreal calculateNiceNum(qreal range, bool round);
|
|
||||||
|
|
||||||
qreal m_rangeMin;
|
qreal m_rangeMin;
|
||||||
qreal m_rangeMax;
|
qreal m_rangeMax;
|
||||||
|
@ -144,6 +144,7 @@ void QObjectPropertyModel::translatePropertyName()
|
|||||||
tr("chartType");
|
tr("chartType");
|
||||||
tr("drawLegendBorder");
|
tr("drawLegendBorder");
|
||||||
tr("labelsField");
|
tr("labelsField");
|
||||||
|
tr("xAxisField");
|
||||||
tr("legendAlign");
|
tr("legendAlign");
|
||||||
tr("series");
|
tr("series");
|
||||||
tr("titleAlign");
|
tr("titleAlign");
|
||||||
@ -170,6 +171,8 @@ void QObjectPropertyModel::translatePropertyName()
|
|||||||
tr("removeGap");
|
tr("removeGap");
|
||||||
tr("dropPrinterMargins");
|
tr("dropPrinterMargins");
|
||||||
tr("notPrintIfEmpty");
|
tr("notPrintIfEmpty");
|
||||||
|
tr("gridChartLines");
|
||||||
|
tr("horizontalAxisOnTop");
|
||||||
tr("mixWithPriorPage");
|
tr("mixWithPriorPage");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user