summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@digia.com>2012-09-05 10:42:37 +0300
committerMichal Klocek <michal.klocek@digia.com>2012-09-05 11:11:30 +0300
commit8d7d66e44a18136d2d666bce03702543a0a8cf49 (patch)
tree90f9e5b4024a8e7727c23ee2442ddb58f3089dff
parentf20e471e275428d38f222e278327d3b870ce990f (diff)
Refactors layout
* adds sizeHints to layout managers * adds sizeHiint to axes * adds "..." wraping to titles * adds title for axes * adds "..." wraping to legend markers * adds logic for layouting axes vs legend vs plotArea * renames minimumMargins to margin * marings size is always keept * legend takes contentMargins into consideration during layout * charts takes contentMargins into consideration during layout * adds "..." wraping to chartvaleaxisY * adds logic to resize plotArea during scale and scroll
-rw-r--r--plugins/declarative/declarativechart.cpp3
-rw-r--r--src/animations/axisanimation.cpp6
-rw-r--r--src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp85
-rw-r--r--src/axis/barcategoryaxis/chartbarcategoryaxisx_p.h2
-rw-r--r--src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp85
-rw-r--r--src/axis/barcategoryaxis/chartbarcategoryaxisy_p.h2
-rw-r--r--src/axis/categoryaxis/chartcategoryaxisx.cpp76
-rw-r--r--src/axis/categoryaxis/chartcategoryaxisx_p.h2
-rw-r--r--src/axis/categoryaxis/chartcategoryaxisy.cpp74
-rw-r--r--src/axis/categoryaxis/chartcategoryaxisy_p.h2
-rw-r--r--src/axis/chartaxis.cpp150
-rw-r--r--src/axis/chartaxis_p.h34
-rw-r--r--src/axis/datetimeaxis/chartdatetimeaxisx.cpp60
-rw-r--r--src/axis/datetimeaxis/chartdatetimeaxisx_p.h2
-rw-r--r--src/axis/datetimeaxis/chartdatetimeaxisy.cpp61
-rw-r--r--src/axis/datetimeaxis/chartdatetimeaxisy_p.h2
-rw-r--r--src/axis/qabstractaxis.cpp84
-rw-r--r--src/axis/qabstractaxis.h13
-rw-r--r--src/axis/qabstractaxis_p.h6
-rw-r--r--src/axis/valueaxis/chartvalueaxisx.cpp75
-rw-r--r--src/axis/valueaxis/chartvalueaxisx_p.h2
-rw-r--r--src/axis/valueaxis/chartvalueaxisy.cpp90
-rw-r--r--src/axis/valueaxis/chartvalueaxisy_p.h2
-rw-r--r--src/chartbackground_p.h1
-rw-r--r--src/chartlayout.cpp239
-rw-r--r--src/chartlayout_p.h32
-rw-r--r--src/chartpresenter.cpp135
-rw-r--r--src/chartpresenter_p.h19
-rw-r--r--src/charttitle.cpp94
-rw-r--r--src/charttitle_p.h53
-rw-r--r--src/domain.cpp1
-rw-r--r--src/legend/legendlayout.cpp118
-rw-r--r--src/legend/legendmarker.cpp37
-rw-r--r--src/legend/legendmarker_p.h1
-rw-r--r--src/qchart.cpp10
-rw-r--r--src/qchart.h6
-rw-r--r--src/src.pro7
37 files changed, 1228 insertions, 443 deletions
diff --git a/plugins/declarative/declarativechart.cpp b/plugins/declarative/declarativechart.cpp
index 572befde..6ee43be3 100644
--- a/plugins/declarative/declarativechart.cpp
+++ b/plugins/declarative/declarativechart.cpp
@@ -245,7 +245,7 @@ DeclarativeChart::DeclarativeChart(QDeclarativeItem *parent)
void DeclarativeChart::changeMinimumMargins(int top, int bottom, int left, int right)
{
- m_chart->setMinimumMargins(QMargins(left, top, right, bottom));
+ m_chart->setMargins(QMargins(left, top, right, bottom));
emit minimumMarginsChanged();
emit plotAreaChanged(m_chart->plotArea());
}
@@ -501,6 +501,7 @@ qreal DeclarativeChart::topMargin()
qreal DeclarativeChart::bottomMargin()
{
+
qWarning() << "ChartView.bottomMargin is deprecated. Use minimumMargins and plotArea instead.";
return m_chart->plotArea().bottom();
}
diff --git a/src/animations/axisanimation.cpp b/src/animations/axisanimation.cpp
index 8a10c848..0d004d6f 100644
--- a/src/animations/axisanimation.cpp
+++ b/src/animations/axisanimation.cpp
@@ -20,6 +20,7 @@
#include "axisanimation_p.h"
#include "chartaxis_p.h"
+#include "chartpresenter_p.h"
#include <QTimer>
#include <QDebug>
@@ -61,7 +62,7 @@ void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayo
switch (m_type) {
case ZoomOutAnimation: {
- QRectF rect = m_axis->geometry();
+ QRectF rect = m_axis->presenter()->chartsGeometry();
oldLayout.resize(newLayout.count());
for(int i = 0, j = oldLayout.count() - 1; i < (oldLayout.count() + 1) / 2; ++i, --j) {
@@ -94,7 +95,7 @@ void AxisAnimation::setValues(QVector<qreal> &oldLayout, QVector<qreal> &newLayo
break;
default: {
oldLayout.resize(newLayout.count());
- QRectF rect = m_axis->geometry();
+ QRectF rect = m_axis->presenter()->chartsGeometry();
for(int i = 0, j = oldLayout.count() - 1; i < oldLayout.count(); ++i, --j)
oldLayout[i] = m_axis->axisType() == ChartAxis::X_AXIS ? rect.left() : rect.top();
}
@@ -131,7 +132,6 @@ void AxisAnimation::updateCurrentValue (const QVariant &value )
Q_ASSERT(vector.count() != 0);
m_axis->setLayout(vector);
m_axis->updateGeometry();
- m_axis->checkLayout();
}
}
diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp
index 072c1fd2..9290cd4d 100644
--- a/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp
+++ b/src/axis/barcategoryaxis/chartbarcategoryaxisx.cpp
@@ -21,6 +21,7 @@
#include "chartbarcategoryaxisx_p.h"
#include "chartpresenter_p.h"
#include "qbarcategoryaxis_p.h"
+#include <QFontMetrics>
#include <QDebug>
#include <qmath.h>
@@ -47,23 +48,25 @@ QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
QVector<qreal> points;
points.resize(count+2);
- const qreal delta = m_rect.width()/(count);
+ QRectF rect = presenter()->chartsGeometry();
+
+ const qreal delta = rect.width()/(count);
qreal offset =-m_min-0.5;
if(delta<1) return points;
if(offset<=0) {
- offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta) + delta;
+ offset = int(offset * rect.width()/(m_max - m_min))%int(delta) + delta;
}
else {
- offset = int(offset * m_rect.width()/(m_max - m_min))%int(delta);
+ offset = int(offset * rect.width()/(m_max - m_min))%int(delta);
}
- points[0] = m_rect.left();
- points[count+1] = m_rect.right();
+ points[0] = rect.left();
+ points[count+1] = rect.right();
for (int i = 0; i < count; ++i) {
- qreal x = offset + i * delta + m_rect.left();
+ qreal x = offset + i * delta + rect.left();
points[i+1] = x;
}
return points;
@@ -72,9 +75,10 @@ QVector<qreal> ChartBarCategoryAxisX::calculateLayout() const
QStringList ChartBarCategoryAxisX::createCategoryLabels(const QVector<qreal>& layout) const
{
QStringList result;
- qreal d = (m_max - m_min)/m_rect.width();
+ QRectF rect = presenter()->chartsGeometry();
+ qreal d = (m_max - m_min)/rect.width();
for (int i = 0;i < layout.count()-1; ++i) {
- qreal x = qFloor((((layout[i+1] + layout[i])/2-m_rect.left())*d + m_min+0.5));
+ qreal x = qFloor((((layout[i+1] + layout[i])/2-rect.left())*d + m_min+0.5));
if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
result << m_categoriesAxis->categories().at(x);
}
@@ -92,9 +96,6 @@ void ChartBarCategoryAxisX::updateGeometry()
{
const QVector<qreal>& layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
-
if(layout.isEmpty()) return;
QStringList ticksList = createCategoryLabels(layout);
@@ -107,15 +108,17 @@ void ChartBarCategoryAxisX::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
- const qreal delta = m_rect.width()/(m_categoriesAxis->d_ptr->count());
+ QRectF chartRect = presenter()->chartsGeometry();
+
+ const qreal delta = chartRect.width()/(m_categoriesAxis->d_ptr->count());
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
+ lineItem->setLine( chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
- qreal width = m_rect.left();
+ qreal width = chartRect.left();
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
+ lineItem->setLine(layout[i], chartRect.top(), layout[i], chartRect.bottom());
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
labelItem->setText(ticksList.at(i));
const QRectF& rect = labelItem->boundingRect();
@@ -123,12 +126,12 @@ void ChartBarCategoryAxisX::updateGeometry()
labelItem->setTransformOriginPoint(center.x(), center.y());
if(i==0){
- labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), m_rect.bottom() + label_padding);
+ labelItem->setPos(layout[i+1] - (delta)/2 - center.x(), chartRect.bottom() + label_padding);
}else{
- labelItem->setPos(layout[i] + (delta)/2 - center.x(), m_rect.bottom() + label_padding);
+ labelItem->setPos(layout[i] + (delta)/2 - center.x(), chartRect.bottom() + label_padding);
}
- if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()>m_rect.right()) {
+ if(labelItem->pos().x()<=width || labelItem->pos().x()+ rect.width()> chartRect.right()) {
labelItem->setVisible(false);
}
else {
@@ -136,15 +139,12 @@ void ChartBarCategoryAxisX::updateGeometry()
width=rect.width()+labelItem->pos().x();
}
- m_minWidth+=rect.width();
- m_minHeight=qMax(rect.height()+label_padding,m_minHeight);
-
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
+ rectItem->setRect(layout[i-1], chartRect.top(),layout[i]-layout[i-1], chartRect.height());
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
+ lineItem->setLine(layout[i], chartRect.bottom(),layout[i], chartRect.bottom()+5);
}
}
@@ -158,4 +158,43 @@ void ChartBarCategoryAxisX::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartBarCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList = createCategoryLabels(ChartAxis::layout());
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ width = fn.boundingRect("...").width();
+ height = fn.height()+label_padding;
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ case Qt::PreferredSize:{
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ width+=rect.width();
+ height=qMax(rect.height()+label_padding,height);
+ }
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisx_p.h b/src/axis/barcategoryaxis/chartbarcategoryaxisx_p.h
index 377d4d54..2340ff7d 100644
--- a/src/axis/barcategoryaxis/chartbarcategoryaxisx_p.h
+++ b/src/axis/barcategoryaxis/chartbarcategoryaxisx_p.h
@@ -45,7 +45,7 @@ public:
~ChartBarCategoryAxisX();
AxisType axisType() const { return X_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
QVector<qreal> calculateLayout() const;
void updateGeometry();
diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp
index f5602368..1a8071aa 100644
--- a/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp
+++ b/src/axis/barcategoryaxis/chartbarcategoryaxisy.cpp
@@ -22,6 +22,7 @@
#include "chartpresenter_p.h"
#include "qbarcategoryaxis_p.h"
#include <qmath.h>
+#include <QFontMetrics>
#include <QDebug>
static int label_padding = 5;
@@ -46,23 +47,25 @@ QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
QVector<qreal> points;
points.resize(count+2);
- const qreal delta = m_rect.height()/(count);
+ QRectF rect = presenter()->chartsGeometry();
+
+ const qreal delta = rect.height()/(count);
qreal offset = - m_min - 0.5;
if(delta<1) return points;
if(offset<=0) {
- offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta) + delta;
+ offset = int(offset * rect.height()/(m_max - m_min))%int(delta) + delta;
}
else {
- offset = int(offset * m_rect.height()/(m_max - m_min))%int(delta);
+ offset = int(offset * rect.height()/(m_max - m_min))%int(delta);
}
- points[0] = m_rect.bottom();
- points[count+1] = m_rect.top();
+ points[0] = rect.bottom();
+ points[count+1] = rect.top();
for (int i = 0; i < count; ++i) {
- int y = m_rect.bottom() - i * delta - offset;
+ int y = rect.bottom() - i * delta - offset;
points[i+1] = y;
}
return points;
@@ -71,9 +74,10 @@ QVector<qreal> ChartBarCategoryAxisY::calculateLayout() const
QStringList ChartBarCategoryAxisY::createCategoryLabels(const QVector<qreal>& layout) const
{
QStringList result;
- qreal d = (m_max - m_min)/m_rect.height();
+ QRectF rect = presenter()->chartsGeometry();
+ qreal d = (m_max - m_min)/rect.height();
for (int i = 0;i < layout.count()-1; ++i) {
- qreal x = qFloor(((m_rect.height()- (layout[i+1] + layout[i])/2 + m_rect.top())*d + m_min+0.5));
+ qreal x = qFloor(((rect.height()- (layout[i+1] + layout[i])/2 + rect.top())*d + m_min+0.5));
if ((x < m_categoriesAxis->categories().count()) && (x >= 0)) {
result << m_categoriesAxis->categories().at(x);
}
@@ -90,9 +94,6 @@ void ChartBarCategoryAxisY::updateGeometry()
{
const QVector<qreal>& layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
-
if(layout.isEmpty()) return;
QStringList ticksList = createCategoryLabels(layout);
@@ -105,15 +106,17 @@ void ChartBarCategoryAxisY::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
- const qreal delta = m_rect.height()/(m_categoriesAxis->d_ptr->count());
+ QRectF chartRect = presenter()->chartsGeometry();
+
+ const qreal delta = chartRect.height()/(m_categoriesAxis->d_ptr->count());
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
+ lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
- qreal height = m_rect.bottom();
+ qreal height = chartRect.bottom();
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
+ lineItem->setLine(chartRect.left() , layout[i], chartRect.right(), layout[i]);
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
labelItem->setText(ticksList.at(i));
const QRectF& rect = labelItem->boundingRect();
@@ -121,13 +124,13 @@ void ChartBarCategoryAxisY::updateGeometry()
labelItem->setTransformOriginPoint(center.x(), center.y());
if(i==0) {
- labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
+ labelItem->setPos(chartRect.left() - rect.width() - label_padding ,layout[i+1] + (delta)/2 - center.y());
}
else {
- labelItem->setPos(m_rect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
+ labelItem->setPos(chartRect.left() - rect.width() - label_padding ,layout[i] - (delta)/2 - center.y());
}
- if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < m_rect.top()) {
+ if(labelItem->pos().y()+rect.height()>= height || labelItem->pos().y() < chartRect.top()) {
labelItem->setVisible(false);
}
else {
@@ -135,15 +138,12 @@ void ChartBarCategoryAxisY::updateGeometry()
height=labelItem->pos().y();
}
- m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
- m_minHeight+=rect.height();
-
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
+ rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
+ lineItem->setLine(chartRect.left()-5,layout[i],chartRect.left(),layout[i]);
}
}
@@ -160,4 +160,43 @@ void ChartBarCategoryAxisY::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartBarCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList = createCategoryLabels(ChartAxis::layout());
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ width = fn.boundingRect("...").width() + label_padding;
+ height = fn.height();
+ width+=base.width();
+ height=qMax(height,base.height());
+ sh = QSizeF(width,height);
+ break;
+ case Qt::PreferredSize:{
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ height+=rect.height();
+ width=qMax(rect.width()+label_padding,width);
+ }
+ height=qMax(height,base.height());
+ width+=base.width();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/barcategoryaxis/chartbarcategoryaxisy_p.h b/src/axis/barcategoryaxis/chartbarcategoryaxisy_p.h
index 1db8aef5..1bf399bc 100644
--- a/src/axis/barcategoryaxis/chartbarcategoryaxisy_p.h
+++ b/src/axis/barcategoryaxis/chartbarcategoryaxisy_p.h
@@ -45,7 +45,7 @@ public:
~ChartBarCategoryAxisY();
AxisType axisType() const { return Y_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
QVector<qreal> calculateLayout() const;
void updateGeometry();
diff --git a/src/axis/categoryaxis/chartcategoryaxisx.cpp b/src/axis/categoryaxis/chartcategoryaxisx.cpp
index 59d490a5..bd2c27a3 100644
--- a/src/axis/categoryaxis/chartcategoryaxisx.cpp
+++ b/src/axis/categoryaxis/chartcategoryaxisx.cpp
@@ -47,16 +47,18 @@ QVector<qreal> ChartCategoryAxisX::calculateLayout() const
if (tickCount < 2)
return points;
+ QRectF rect = presenter()->chartsGeometry();
+
qreal range = axis->max() - axis->min();
if (range > 0) {
points.resize(tickCount);
- qreal scale = m_rect.width() / range;
+ qreal scale = rect.width() / range;
for (int i = 0; i < tickCount; ++i)
if (i < tickCount - 1) {
- int x = (axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + m_rect.left();
+ int x = (axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + rect.left();
points[i] = x;
} else {
- int x = (axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + m_rect.left();
+ int x = (axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + rect.left();
points[i] = x;
}
}
@@ -67,9 +69,6 @@ void ChartCategoryAxisX::updateGeometry()
{
const QVector<qreal>& layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
-
if(layout.isEmpty()) return;
QCategoryAxis *categoryAxis = qobject_cast<QCategoryAxis *>(m_chartAxis);
@@ -85,13 +84,14 @@ void ChartCategoryAxisX::updateGeometry()
labels.at(i)->setVisible(false);
}
+ QRectF chartRect = presenter()->chartsGeometry();
// axis base line
+
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
+ lineItem->setLine(chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
for (int i = 0; i < layout.size(); ++i) {
- // label items
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
if (i < ticksList.count()) {
labelItem->setText(ticksList.at(i));
@@ -99,43 +99,42 @@ void ChartCategoryAxisX::updateGeometry()
const QRectF& rect = labelItem->boundingRect();
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
+
if (i < layout.size() - 1) {
- labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), m_rect.bottom() + label_padding);
+ labelItem->setPos(layout[i] + (layout[i + 1] - layout[i]) / 2 - center.x(), chartRect.bottom() + label_padding);
} else {
- labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
+ labelItem->setPos(layout[i] - center.x(), chartRect.bottom() + label_padding);
}
// check if the label should be shown
- if (labelItem->pos().x() + center.x() < m_rect.left() || labelItem->pos().x() + center.x() > m_rect.right())
+ if (labelItem->pos().x() + center.x() < chartRect.left() || labelItem->pos().x() + center.x() > chartRect.right())
labelItem->setVisible(false);
else
labelItem->setVisible(true);
- m_minWidth += rect.width();
- m_minHeight = qMax(rect.height()+ label_padding, m_minHeight);
-
if ((i + 1) % 2 && i > 1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i / 2 - 1));
- rectItem->setRect(layout[i - 1],m_rect.top(),layout[i]-layout[i - 1],m_rect.height());
+ rectItem->setRect(layout[i - 1],chartRect.top(),layout[i]-layout[i - 1],chartRect.height());
}
// grid lines and axis line ticks
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setPos(layout[i], m_rect.top());
- lineItem->setLine(0, 0, 0, m_rect.height());
+ lineItem->setPos(layout[i], chartRect.top());
+ lineItem->setLine(0, 0, 0, chartRect.height());
QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- tickLineItem->setPos(layout[i], m_rect.bottom());
+ tickLineItem->setPos(layout[i], chartRect.bottom());
tickLineItem->setLine(0, 0, 0, 5);
// check if the grid line and the axis tick should be shown
- if (lineItem->pos().x() < m_rect.left() || lineItem->pos().x() > m_rect.right()) {
+ if (lineItem->pos().x() < chartRect.left() || lineItem->pos().x() > chartRect.right()) {
lineItem->setVisible(false);
tickLineItem->setVisible(false);
} else {
lineItem->setVisible(true);
tickLineItem->setVisible(true);
}
+
}
}
@@ -146,4 +145,43 @@ void ChartCategoryAxisX::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartCategoryAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList ; //TODO:
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ width = fn.boundingRect("...").width();
+ height = fn.height() + label_padding;
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ case Qt::PreferredSize: {
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ width+=rect.width();
+ height=qMax(rect.height()+label_padding,height);
+ }
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/categoryaxis/chartcategoryaxisx_p.h b/src/axis/categoryaxis/chartcategoryaxisx_p.h
index 60191f42..4b380bcc 100644
--- a/src/axis/categoryaxis/chartcategoryaxisx_p.h
+++ b/src/axis/categoryaxis/chartcategoryaxisx_p.h
@@ -44,7 +44,7 @@ public:
~ChartCategoryAxisX();
AxisType axisType() const { return X_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
QVector<qreal> calculateLayout() const;
void updateGeometry();
diff --git a/src/axis/categoryaxis/chartcategoryaxisy.cpp b/src/axis/categoryaxis/chartcategoryaxisy.cpp
index 82f2e323..80aeab39 100644
--- a/src/axis/categoryaxis/chartcategoryaxisy.cpp
+++ b/src/axis/categoryaxis/chartcategoryaxisy.cpp
@@ -47,16 +47,18 @@ QVector<qreal> ChartCategoryAxisY::calculateLayout() const
if (tickCount < 2)
return points;
+ QRectF rect = presenter()->chartsGeometry();
+
qreal range = axis->max() - axis->min();
if (range > 0) {
points.resize(tickCount);
- qreal scale = m_rect.height() / range;
+ qreal scale = rect.height() / range;
for (int i = 0; i < tickCount; ++i)
if (i < tickCount - 1) {
- int y = -(axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + m_rect.bottom();
+ int y = -(axis->startValue(axis->categoriesLabels().at(i)) - axis->min()) * scale + rect.bottom();
points[i] = y;
} else {
- int y = -(axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + m_rect.bottom();
+ int y = -(axis->endValue(axis->categoriesLabels().at(i - 1)) - axis->min()) * scale + rect.bottom();
points[i] = y;
}
}
@@ -67,8 +69,6 @@ QVector<qreal> ChartCategoryAxisY::calculateLayout() const
void ChartCategoryAxisY::updateGeometry()
{
const QVector<qreal> &layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
if(layout.isEmpty()) {
return;
@@ -88,9 +88,11 @@ void ChartCategoryAxisY::updateGeometry()
labels.at(i)->setVisible(false);
}
+ QRectF chartRect = presenter()->chartsGeometry();
+
// axis base line
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
+ lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
for (int i = 0; i < layout.size(); ++i) {
@@ -104,13 +106,14 @@ void ChartCategoryAxisY::updateGeometry()
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
+
if (i < layout.size() - 1)
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
+ labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i] + (layout[i + 1] - layout[i]) / 2 - center.y());
else
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
+ labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
// check if the label should be shown
- if (labelItem->pos().y() + center.y() < m_rect.top() || labelItem->pos().y() + center.y() > m_rect.bottom())
+ if (labelItem->pos().y() + center.y() < chartRect.top() || labelItem->pos().y() + center.y() > chartRect.bottom())
labelItem->setVisible(false);
else
labelItem->setVisible(true);
@@ -123,31 +126,29 @@ void ChartCategoryAxisY::updateGeometry()
// height=labelItem->pos().y();
// }
- m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
- m_minHeight+=rect.height();
-
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
+ rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
}
// grid lines and axis line ticks
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setPos(m_rect.left(), layout[i]);
- lineItem->setLine(0, 0, m_rect.width(), 0);
+ lineItem->setPos(chartRect.left(), layout[i]);
+ lineItem->setLine(0, 0, chartRect.width(), 0);
QGraphicsLineItem *tickLineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- tickLineItem->setPos(m_rect.left(), layout[i]);
+ tickLineItem->setPos(chartRect.left(), layout[i]);
tickLineItem->setLine(-5, 0, 0, 0);
// check if the grid line and the axis tick should be shown
- if (lineItem->pos().y() < m_rect.top() || lineItem->pos().y() > m_rect.bottom()) {
+ if (lineItem->pos().y() < chartRect.top() || lineItem->pos().y() > chartRect.bottom()) {
lineItem->setVisible(false);
tickLineItem->setVisible(false);
} else {
lineItem->setVisible(true);
tickLineItem->setVisible(true);
}
+
}
}
@@ -158,4 +159,43 @@ void ChartCategoryAxisY::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartCategoryAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList; //TODO::
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ width = fn.boundingRect("...").width()+label_padding;
+ height = fn.height();
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ case Qt::PreferredSize:{
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ height+=rect.height();
+ width=qMax(rect.width()+label_padding,width);
+ }
+ height=qMax(height,base.height());
+ width+=base.width();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/categoryaxis/chartcategoryaxisy_p.h b/src/axis/categoryaxis/chartcategoryaxisy_p.h
index 9c3186c2..41970b92 100644
--- a/src/axis/categoryaxis/chartcategoryaxisy_p.h
+++ b/src/axis/categoryaxis/chartcategoryaxisy_p.h
@@ -44,7 +44,7 @@ public:
~ChartCategoryAxisY();
AxisType axisType() const { return Y_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
QVector<qreal> calculateLayout() const;
void updateGeometry();
diff --git a/src/axis/chartaxis.cpp b/src/axis/chartaxis.cpp
index cdf79be5..7018ac66 100644
--- a/src/axis/chartaxis.cpp
+++ b/src/axis/chartaxis.cpp
@@ -27,6 +27,7 @@
#include <QDateTime>
#include <QValueAxis>
#include <QGraphicsLayout>
+#include <QFontMetrics>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -37,11 +38,10 @@ ChartAxis::ChartAxis(QAbstractAxis *axis,ChartPresenter *presenter) : ChartEleme
m_shades(new QGraphicsItemGroup(presenter->rootItem())),
m_labels(new QGraphicsItemGroup(presenter->rootItem())),
m_arrow(new QGraphicsItemGroup(presenter->rootItem())),
+ m_title(new QGraphicsSimpleTextItem(presenter->rootItem())),
m_min(0),
m_max(0),
- m_animation(0),
- m_minWidth(0),
- m_minHeight(0)
+ m_animation(0)
{
//initial initialization
m_arrow->setZValue(ChartPresenter::AxisZValue);
@@ -139,7 +139,6 @@ void ChartAxis::updateLayout(QVector<qreal> &layout)
else {
setLayout(layout);
updateGeometry();
- checkLayout();
}
}
@@ -231,7 +230,15 @@ void ChartAxis::setLabelsFont(const QFont &font)
foreach(QGraphicsItem* item , m_labels->childItems()) {
static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
}
- m_font = font;
+ if(m_font!=font) {
+ m_font = font;
+ foreach(QGraphicsItem* item , m_labels->childItems()) {
+ static_cast<QGraphicsSimpleTextItem*>(item)->setFont(font);
+ }
+ QGraphicsLayoutItem::updateGeometry();
+ presenter()->layout()->invalidate();
+
+ }
}
void ChartAxis::setShadesBrush(const QBrush &brush)
@@ -264,7 +271,7 @@ void ChartAxis::setGridPen(const QPen &pen)
bool ChartAxis::isEmpty()
{
- return m_rect.isEmpty() || qFuzzyIsNull(m_min - m_max);
+ return !m_rect.isValid() || presenter()->chartsGeometry().isEmpty() || qFuzzyIsNull(m_min - m_max);
}
void ChartAxis::handleDomainUpdated()
@@ -289,8 +296,20 @@ void ChartAxis::handleDomainUpdated()
m_max = max;
if (!isEmpty()) {
+
QVector<qreal> layout = calculateLayout();
updateLayout(layout);
+ QSizeF before = effectiveSizeHint(Qt::MinimumSize);
+
+ QSizeF after= sizeHint(Qt::MinimumSize);
+
+ if(before!=after) {
+ QGraphicsLayoutItem::updateGeometry();
+ //we don't want to call invalidate on layout, since it will change minimum size of component,
+ //which we would like to avoid since it causes nasty flips when scrolling or zooming,
+ //instead recalculate layout and use plotArea for extra space.
+ presenter()->layout()->setGeometry(presenter()->layout()->geometry());
+ }
}
}
}
@@ -314,7 +333,17 @@ void ChartAxis::handleAxisUpdated()
setGridPen(m_chartAxis->gridLinePen());
setShadesPen(m_chartAxis->shadesPen());
setShadesBrush(m_chartAxis->shadesBrush());
+ setTitleText(m_chartAxis->title());
+}
+void ChartAxis::setTitleText(const QString& title)
+{
+ if(m_titleText!=title) {
+ m_titleText = title;
+ m_rect = QRect();
+ QGraphicsLayoutItem::updateGeometry();
+ presenter()->layout()->invalidate();
+ }
}
void ChartAxis::hide()
@@ -325,42 +354,64 @@ void ChartAxis::hide()
setShadesVisibility(false);
}
-void ChartAxis::handleGeometryChanged(const QRectF &rect)
+void ChartAxis::setGeometry(const QRectF &rect)
{
- if(m_rect != rect)
- {
+
m_rect = rect;
+
if (isEmpty()) return;
+
+ if(!m_titleText.isNull()) {
+ QFontMetrics fn(m_title->font());
+
+ int size(0);
+
+ QRectF chartRect = presenter()->chartsGeometry();
+
+ if(orientation()==Qt::Horizontal)
+ size = chartRect.width();
+ else if(orientation()==Qt::Vertical)
+ size = chartRect.height();
+
+ if (fn.boundingRect(m_titleText).width() > size)
+ {
+ QString string = m_titleText + "...";
+ while (fn.boundingRect(string).width() > size && string.length() > 3)
+ string.remove(string.length() - 4, 1);
+ m_title->setText(string);
+ }
+ else
+ m_title->setText(m_titleText);
+
+ QPointF center = chartRect.center() - m_title->boundingRect().center();
+ if(orientation()==Qt::Horizontal) {
+ m_title->setPos(center.x(),m_rect.bottom()-m_title->boundingRect().height());
+ }
+ else if(orientation()==Qt::Vertical) {
+ m_title->setTransformOriginPoint(m_title->boundingRect().center());
+ m_title->setRotation(270);
+ m_title->setPos(m_rect.left()- m_title->boundingRect().width()/2+m_title->boundingRect().height()/2,center.y());
+ }
+ }
+
QVector<qreal> layout = calculateLayout();
updateLayout(layout);
- }
-}
-
-qreal ChartAxis::minimumWidth()
-{
- if(m_minWidth == 0) updateGeometry();
- return m_minWidth;
}
-qreal ChartAxis::minimumHeight()
-{
- if(m_minHeight == 0) updateGeometry();
- return m_minHeight;
-}
-
-
void ChartAxis::axisSelected()
{
- qDebug()<<"TODO: axis clicked";
+ //TODO: axis clicked;
}
-void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int ticks) const
+QStringList ChartAxis::createNumberLabels(qreal min, qreal max, int ticks) const
{
Q_ASSERT(max>min);
Q_ASSERT(ticks>1);
+ QStringList labels;
+
int n = qMax(int(-qFloor(log10((max-min)/(ticks-1)))),0);
n++;
@@ -381,17 +432,54 @@ void ChartAxis::createNumberLabels(QStringList &labels,qreal min, qreal max, int
labels << QString().sprintf(array, value);
}
}
+
+ return labels;
}
-void ChartAxis::checkLayout()
+Qt::Orientation ChartAxis::orientation() const
{
- if(m_minWidth > m_rect.width()) {
- presenter()->layout()->invalidate();
- }
+ return m_chartAxis->orientation();
+}
- if(m_minHeight > m_rect.height()) {
- presenter()->layout()->invalidate();
+bool ChartAxis::isVisible()
+{
+ return m_chartAxis->isVisible();
+}
+
+QSizeF ChartAxis::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+
+ Q_UNUSED(constraint);
+ QFontMetrics fn(m_title->font());
+ QSizeF sh;
+
+ if(m_titleText.isNull()) return sh;
+
+ switch(which) {
+ case Qt::MinimumSize:
+ if(orientation()==Qt::Horizontal) {
+ sh = QSizeF(fn.boundingRect ("...").width(),fn.height());
+ }
+ else if(orientation()==Qt::Vertical) {
+ sh = QSizeF(fn.height(),fn.boundingRect ("...").width());
+ }
+
+ break;
+ case Qt::MaximumSize:
+ case Qt::PreferredSize:
+ if(orientation()==Qt::Horizontal) {
+ sh = QSizeF(fn.boundingRect(m_chartAxis->title()).width(),fn.height());
+ }
+ else if(orientation()==Qt::Vertical) {
+ sh = QSizeF(fn.height(),fn.boundingRect(m_chartAxis->title()).width());
+ }
+
+ break;
+ default:
+ break;
}
+
+ return sh;
}
#include "moc_chartaxis_p.cpp"
diff --git a/src/axis/chartaxis_p.h b/src/axis/chartaxis_p.h
index 389e6540..acfc127a 100644
--- a/src/axis/chartaxis_p.h
+++ b/src/axis/chartaxis_p.h
@@ -34,6 +34,7 @@
#include "chartelement_p.h"
#include "axisanimation_p.h"
#include <QGraphicsItem>
+#include <QGraphicsLayoutItem>
#include <QFont>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -41,9 +42,10 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE
class QAbstractAxis;
class ChartPresenter;
-class ChartAxis : public ChartElement
+class ChartAxis : public ChartElement, public QGraphicsLayoutItem
{
Q_OBJECT
+ Q_INTERFACES(QGraphicsLayoutItem)
public:
enum AxisType{ X_AXIS,Y_AXIS };
@@ -81,29 +83,38 @@ public:
void setLabelsBrush(const QBrush &brush);
void setLabelsFont(const QFont &font);
+ void setTitlePen(const QPen &pen);
+ void setTitleBrush(const QBrush &brush);
+ void setTitleFont(const QFont &font);
+ void setTitleText(const QString& title);
+
+
void setLayout(QVector<qreal> &layout);
QVector<qreal> layout() const { return m_layoutVector; }
void setAnimation(AxisAnimation* animation);
ChartAnimation* animation() const { return m_animation; };
- QRectF geometry() const { return m_rect; }
-
- qreal minimumWidth();
- qreal minimumHeight();
+ Qt::Orientation orientation() const;
+ bool isVisible();
void hide();
+ void setGeometry(const QRectF &size);
+ QRectF geometry() const { return m_rect; }
+
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint = QSizeF()) const;
+
protected:
virtual void updateGeometry() = 0;
virtual QVector<qreal> calculateLayout() const = 0;
- void createNumberLabels(QStringList &labels,qreal min, qreal max,int ticks) const;
- void checkLayout();
+ QStringList createNumberLabels(qreal min, qreal max,int ticks) const;
+
public Q_SLOTS:
virtual void handleAxisUpdated();
virtual void handleDomainUpdated();
- void handleGeometryChanged(const QRectF &size);
+
private:
inline bool isEmpty();
@@ -114,19 +125,20 @@ private:
protected:
QAbstractAxis* m_chartAxis;
- QRectF m_rect;
int m_labelsAngle;
+ //TODO: to be removed
+ QRectF m_rect;
QScopedPointer<QGraphicsItemGroup> m_grid;
QScopedPointer<QGraphicsItemGroup> m_shades;
QScopedPointer<QGraphicsItemGroup> m_labels;
QScopedPointer<QGraphicsItemGroup> m_arrow;
+ QGraphicsSimpleTextItem* m_title;
QVector<qreal> m_layoutVector;
qreal m_min;
qreal m_max;
AxisAnimation *m_animation;
- qreal m_minWidth;
- qreal m_minHeight;
QFont m_font;
+ QString m_titleText;
friend class AxisAnimation;
friend class AxisItem;
diff --git a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp
index a7329512..a6e441e5 100644
--- a/src/axis/datetimeaxis/chartdatetimeaxisx.cpp
+++ b/src/axis/datetimeaxis/chartdatetimeaxisx.cpp
@@ -61,10 +61,10 @@ QVector<qreal> ChartDateTimeAxisX::calculateLayout() const
QVector<qreal> points;
points.resize(m_tickCount);
-
- const qreal deltaX = m_rect.width()/(m_tickCount-1);
+ QRectF rect = presenter()->chartsGeometry();
+ const qreal deltaX = rect.width()/(m_tickCount-1);
for (int i = 0; i < m_tickCount; ++i) {
- int x = i * deltaX + m_rect.left();
+ int x = i * deltaX + rect.left();
points[i] = x;
}
return points;
@@ -74,9 +74,6 @@ void ChartDateTimeAxisX::updateGeometry()
{
const QVector<qreal>& layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
-
if(layout.isEmpty()) return;
QStringList ticksList;
@@ -91,19 +88,21 @@ void ChartDateTimeAxisX::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
+ QRectF chartRect = presenter()->chartsGeometry();
+
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
+ lineItem->setLine(chartRect.left(), chartRect.bottom(), chartRect.right(), chartRect.bottom());
qreal width = 0;
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
+ lineItem->setLine(layout[i], chartRect.top(), layout[i], chartRect.bottom());
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
labelItem->setText(ticksList.at(i));
const QRectF& rect = labelItem->boundingRect();
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
+ labelItem->setPos(layout[i] - center.x(), chartRect.bottom() + label_padding);
if(labelItem->pos().x()<=width){
labelItem->setVisible(false);
@@ -113,15 +112,13 @@ void ChartDateTimeAxisX::updateGeometry()
lineItem->setVisible(true);
width=rect.width()+labelItem->pos().x();
}
- m_minWidth+=rect.width();
- m_minHeight=qMax(rect.height(),m_minHeight);
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
+ rectItem->setRect(layout[i-1],chartRect.top(),layout[i]-layout[i-1],chartRect.height());
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
+ lineItem->setLine(layout[i],chartRect.bottom(),layout[i],chartRect.bottom()+5);
}
}
@@ -133,4 +130,41 @@ void ChartDateTimeAxisX::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartDateTimeAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ sh = QSizeF(fn.boundingRect("...").width(),fn.height());
+ break;
+ case Qt::PreferredSize:{
+
+ const QVector<qreal>& layout = ChartAxis::layout();
+ if(layout.isEmpty()) break;
+ QStringList ticksList;
+
+
+ qreal width=0;
+ qreal height=0;
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ width+=rect.width();
+ height+=qMax(rect.height()+label_padding,height);
+ }
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/datetimeaxis/chartdatetimeaxisx_p.h b/src/axis/datetimeaxis/chartdatetimeaxisx_p.h
index aeb78daa..0e4f170f 100644
--- a/src/axis/datetimeaxis/chartdatetimeaxisx_p.h
+++ b/src/axis/datetimeaxis/chartdatetimeaxisx_p.h
@@ -44,7 +44,7 @@ public:
~ChartDateTimeAxisX();
AxisType axisType() const { return X_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
void handleAxisUpdated();
diff --git a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp
index 07fc0ddc..d92efcc0 100644
--- a/src/axis/datetimeaxis/chartdatetimeaxisy.cpp
+++ b/src/axis/datetimeaxis/chartdatetimeaxisy.cpp
@@ -61,10 +61,10 @@ QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
QVector<qreal> points;
points.resize(m_tickCount);
-
- const qreal deltaY = m_rect.height()/(m_tickCount-1);
+ QRectF rect = presenter()->chartsGeometry();
+ const qreal deltaY = rect.height()/(m_tickCount-1);
for (int i = 0; i < m_tickCount; ++i) {
- int y = i * -deltaY + m_rect.bottom();
+ int y = i * -deltaY + rect.bottom();
points[i] = y;
}
@@ -74,8 +74,6 @@ QVector<qreal> ChartDateTimeAxisY::calculateLayout() const
void ChartDateTimeAxisY::updateGeometry()
{
const QVector<qreal> &layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
if(layout.isEmpty()) return;
@@ -91,14 +89,16 @@ void ChartDateTimeAxisY::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
- qreal height = 2*m_rect.bottom();
+ QRectF chartRect = presenter()->chartsGeometry();
+
+ qreal height = chartRect.bottom();
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
+ lineItem->setLine(chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
+ lineItem->setLine(chartRect.left() , layout[i], chartRect.right(), layout[i]);
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
labelItem->setText(ticksList.at(i));
@@ -106,7 +106,7 @@ void ChartDateTimeAxisY::updateGeometry()
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
+ labelItem->setPos(chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
if(labelItem->pos().y()+rect.height()>height) {
labelItem->setVisible(false);
@@ -118,15 +118,12 @@ void ChartDateTimeAxisY::updateGeometry()
height=labelItem->pos().y();
}
- m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
- m_minHeight+=rect.height();
-
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
+ rectItem->setRect(chartRect.left(),layout[i],chartRect.width(),layout[i-1]-layout[i]);
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
+ lineItem->setLine(chartRect.left()-5,layout[i],chartRect.left(),layout[i]);
}
}
@@ -138,5 +135,41 @@ void ChartDateTimeAxisY::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartDateTimeAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+
+ switch (which) {
+ case Qt::MinimumSize:
+ sh = QSizeF(fn.boundingRect("...").width(),fn.height());
+ break;
+ case Qt::PreferredSize:{
+
+ const QVector<qreal>& layout = ChartAxis::layout();
+ if(layout.isEmpty()) break;
+ QStringList ticksList;
+
+
+ qreal width=0;
+ qreal height=0;
+
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ QRectF rect = fn.boundingRect(ticksList.at(i));
+ width+=rect.width();
+ height+=qMax(rect.height()+label_padding,height);
+ }
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/datetimeaxis/chartdatetimeaxisy_p.h b/src/axis/datetimeaxis/chartdatetimeaxisy_p.h
index 2c116887..4e3d5944 100644
--- a/src/axis/datetimeaxis/chartdatetimeaxisy_p.h
+++ b/src/axis/datetimeaxis/chartdatetimeaxisy_p.h
@@ -44,7 +44,7 @@ public:
~ChartDateTimeAxisY();
AxisType axisType() const { return Y_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
void createLabels(QStringList &labels,qreal min, qreal max, int ticks);
QVector<qreal> calculateLayout() const;
diff --git a/src/axis/qabstractaxis.cpp b/src/axis/qabstractaxis.cpp
index b1107890..b098af62 100644
--- a/src/axis/qabstractaxis.cpp
+++ b/src/axis/qabstractaxis.cpp
@@ -458,6 +458,90 @@ QColor QAbstractAxis::labelsColor() const
return d_ptr->m_labelsBrush.color();
}
+void QAbstractAxis::setTitleVisible(bool visible)
+{
+ if (d_ptr->m_titleVisible != visible) {
+ d_ptr->m_titleVisible = visible;
+ d_ptr->emitUpdated();
+ }
+}
+
+bool QAbstractAxis::titleVisible() const
+{
+ return d_ptr->m_titleVisible;
+}
+
+/*!
+ Sets \a pen used to draw title.
+*/
+void QAbstractAxis::setTitlePen(const QPen &pen)
+{
+ if (d_ptr->m_titlePen != pen) {
+ d_ptr->m_titlePen = pen;
+ d_ptr->emitUpdated();
+ }
+}
+
+/*!
+ Returns the pen used to title.
+*/
+QPen QAbstractAxis::titlePen() const
+{
+ return d_ptr->m_titlePen;
+}
+
+/*!
+ Sets \a brush used to draw title.
+ */
+void QAbstractAxis::setTitleBrush(const QBrush &brush)
+{
+ if (d_ptr->m_titleBrush != brush) {
+ d_ptr->m_titleBrush = brush;
+ d_ptr->emitUpdated();
+ }
+}
+
+/*!
+ Returns brush used to draw title.
+*/
+QBrush QAbstractAxis::titleBrush() const
+{
+ return d_ptr->m_titleBrush;
+}
+
+/*!
+ Sets \a font used to draw title.
+*/
+void QAbstractAxis::setTitleFont(const QFont &font)
+{
+ if (d_ptr->m_titleFont != font) {
+ d_ptr->m_titleFont = font;
+ d_ptr->emitUpdated();
+ }
+}
+
+/*!
+ Returns font used to draw title.
+*/
+QFont QAbstractAxis::titleFont() const
+{
+ return d_ptr->m_titleFont;
+}
+
+void QAbstractAxis::setTitle(const QString& title)
+{
+ if (d_ptr->m_title != title) {
+ d_ptr->m_title = title;
+ d_ptr->emitUpdated();
+ }
+}
+
+QString QAbstractAxis::title() const
+{
+ return d_ptr->m_title;
+}
+
+
void QAbstractAxis::setShadesVisible(bool visible)
{
if (d_ptr->m_shadesVisible != visible) {
diff --git a/src/axis/qabstractaxis.h b/src/axis/qabstractaxis.h
index afe1629f..f03376c7 100644
--- a/src/axis/qabstractaxis.h
+++ b/src/axis/qabstractaxis.h
@@ -98,6 +98,19 @@ public:
void setLabelsColor(QColor color);
QColor labelsColor() const;
+ //title handling
+ bool titleVisible() const;
+ void setTitleVisible(bool visible = true);
+ void setTitlePen(const QPen &pen);
+ QPen titlePen() const;
+ void setTitleBrush(const QBrush &brush);
+ QBrush titleBrush() const;
+ void setTitleFont(const QFont &font);
+ QFont titleFont() const;
+ void setTitle(const QString& title);
+ QString title() const;
+
+
//shades handling
bool shadesVisible() const;
void setShadesVisible(bool visible = true);
diff --git a/src/axis/qabstractaxis_p.h b/src/axis/qabstractaxis_p.h
index 7860f7c9..b8df5e98 100644
--- a/src/axis/qabstractaxis_p.h
+++ b/src/axis/qabstractaxis_p.h
@@ -94,6 +94,12 @@ private:
QFont m_labelsFont;
int m_labelsAngle;
+ bool m_titleVisible;
+ QPen m_titlePen;
+ QBrush m_titleBrush;
+ QFont m_titleFont;
+ QString m_title;
+
bool m_shadesVisible;
QPen m_shadesPen;
QBrush m_shadesBrush;
diff --git a/src/axis/valueaxis/chartvalueaxisx.cpp b/src/axis/valueaxis/chartvalueaxisx.cpp
index c7ebe965..040b388f 100644
--- a/src/axis/valueaxis/chartvalueaxisx.cpp
+++ b/src/axis/valueaxis/chartvalueaxisx.cpp
@@ -25,6 +25,7 @@
#include <QGraphicsLayout>
#include <QFontMetrics>
#include <qmath.h>
+#include <QDebug>
static int label_padding = 5;
@@ -46,9 +47,11 @@ QVector<qreal> ChartValueAxisX::calculateLayout() const
QVector<qreal> points;
points.resize(m_tickCount);
- const qreal deltaX = m_rect.width()/(m_tickCount-1);
+ QRectF rect = presenter()->chartsGeometry();
+
+ const qreal deltaX = rect.width()/(m_tickCount-1);
for (int i = 0; i < m_tickCount; ++i) {
- int x = i * deltaX + m_rect.left();
+ int x = i * deltaX + rect.left();
points[i] = x;
}
return points;
@@ -58,14 +61,9 @@ void ChartValueAxisX::updateGeometry()
{
const QVector<qreal>& layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
-
if(layout.isEmpty()) return;
- QStringList ticksList;
-
- createNumberLabels(ticksList,m_min,m_max,layout.size());
+ QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
QList<QGraphicsItem *> lines = m_grid->childItems();
QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,21 +73,24 @@ void ChartValueAxisX::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
+ QRectF chartRrect = presenter()->chartsGeometry();
+
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left(), m_rect.bottom(), m_rect.right(), m_rect.bottom());
+ lineItem->setLine(chartRrect.left(), chartRrect.bottom(), chartRrect.right(), chartRrect.bottom());
qreal width = 0;
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(layout[i], m_rect.top(), layout[i], m_rect.bottom());
+ lineItem->setLine(layout[i], chartRrect.top(), layout[i], chartRrect.bottom());
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
labelItem->setText(ticksList.at(i));
const QRectF& rect = labelItem->boundingRect();
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(layout[i] - center.x(), m_rect.bottom() + label_padding);
-
- if(labelItem->pos().x()<=width){
+ labelItem->setPos(layout[i] - center.x(), chartRrect.bottom() + label_padding);
+ if(labelItem->pos().x() <= width ||
+ labelItem->pos().x() < m_rect.left() ||
+ labelItem->pos().x() + rect.width() > m_rect.right()){
labelItem->setVisible(false);
lineItem->setVisible(false);
}else{
@@ -97,17 +98,14 @@ void ChartValueAxisX::updateGeometry()
lineItem->setVisible(true);
width=rect.width()+labelItem->pos().x();
}
- m_minWidth+=rect.width();
- m_minHeight=qMax(rect.height(),m_minHeight);
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(layout[i-1],m_rect.top(),layout[i]-layout[i-1],m_rect.height());
+ rectItem->setRect(layout[i-1],chartRrect.top(),layout[i]-layout[i-1],chartRrect.height());
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(layout[i],m_rect.bottom(),layout[i],m_rect.bottom()+5);
+ lineItem->setLine(layout[i],chartRrect.bottom(),layout[i],chartRrect.bottom()+5);
}
-
}
void ChartValueAxisX::handleAxisUpdated()
@@ -118,4 +116,45 @@ void ChartValueAxisX::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartValueAxisX::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList = createNumberLabels(m_min,m_max,m_tickCount);
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize:{
+ int count = qMax(ticksList.last().count(),ticksList.first().count());
+ width=fn.averageCharWidth()*count;
+ height=fn.height()+label_padding;
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ }
+ case Qt::PreferredSize:{
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ width+=fn.averageCharWidth()*ticksList.at(i).count();
+
+ }
+ height=fn.height()+label_padding;
+ width=qMax(width,base.width());
+ height+=base.height();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return sh;
+}
+
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/valueaxis/chartvalueaxisx_p.h b/src/axis/valueaxis/chartvalueaxisx_p.h
index bf7a9cce..da48637c 100644
--- a/src/axis/valueaxis/chartvalueaxisx_p.h
+++ b/src/axis/valueaxis/chartvalueaxisx_p.h
@@ -44,7 +44,7 @@ public:
~ChartValueAxisX();
AxisType axisType() const { return X_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
void handleAxisUpdated();
QVector<qreal> calculateLayout() const;
diff --git a/src/axis/valueaxis/chartvalueaxisy.cpp b/src/axis/valueaxis/chartvalueaxisy.cpp
index ea50eb36..5199b67b 100644
--- a/src/axis/valueaxis/chartvalueaxisy.cpp
+++ b/src/axis/valueaxis/chartvalueaxisy.cpp
@@ -25,6 +25,7 @@
#include <QGraphicsLayout>
#include <QFontMetrics>
#include <qmath.h>
+#include <QDebug>
static int label_padding = 5;
@@ -46,9 +47,11 @@ QVector<qreal> ChartValueAxisY::calculateLayout() const
QVector<qreal> points;
points.resize(m_tickCount);
- const qreal deltaY = m_rect.height()/(m_tickCount-1);
+ QRectF rect = presenter()->chartsGeometry();
+
+ const qreal deltaY = rect.height()/(m_tickCount-1);
for (int i = 0; i < m_tickCount; ++i) {
- int y = i * -deltaY + m_rect.bottom();
+ int y = i * -deltaY + rect.bottom();
points[i] = y;
}
@@ -58,14 +61,10 @@ QVector<qreal> ChartValueAxisY::calculateLayout() const
void ChartValueAxisY::updateGeometry()
{
const QVector<qreal> &layout = ChartAxis::layout();
- m_minWidth = 0;
- m_minHeight = 0;
if(layout.isEmpty()) return;
- QStringList ticksList;
-
- createNumberLabels(ticksList,m_min,m_max,layout.size());
+ QStringList ticksList = createNumberLabels(m_min,m_max,layout.size());
QList<QGraphicsItem *> lines = m_grid->childItems();
QList<QGraphicsItem *> labels = m_labels->childItems();
@@ -75,44 +74,55 @@ void ChartValueAxisY::updateGeometry()
Q_ASSERT(labels.size() == ticksList.size());
Q_ASSERT(layout.size() == ticksList.size());
- qreal height = 2*m_rect.bottom();
+ QRectF chartRect = presenter()->chartsGeometry();
+
+ qreal height = m_rect.bottom();
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(axis.at(0));
- lineItem->setLine(m_rect.left() , m_rect.top(), m_rect.left(), m_rect.bottom());
+ lineItem->setLine( chartRect.left() , chartRect.top(), chartRect.left(), chartRect.bottom());
+
+ QFontMetrics fn(m_font);
for (int i = 0; i < layout.size(); ++i) {
QGraphicsLineItem *lineItem = static_cast<QGraphicsLineItem*>(lines.at(i));
- lineItem->setLine(m_rect.left() , layout[i], m_rect.right(), layout[i]);
+ lineItem->setLine( chartRect.left() , layout[i], chartRect.right(), layout[i]);
QGraphicsSimpleTextItem *labelItem = static_cast<QGraphicsSimpleTextItem*>(labels.at(i));
- labelItem->setText(ticksList.at(i));
+ QString text = ticksList.at(i);
+
+ if (fn.boundingRect(text).width() > chartRect.left() - m_rect.left() - label_padding )
+ {
+ QString label = text + "...";
+ while (fn.boundingRect(label).width() > chartRect.left() - m_rect.left() - label_padding && label.length() > 3)
+ label.remove(label.length() - 4, 1);
+ labelItem->setText(label);
+ }else{
+ labelItem->setText(text);
+ }
+
const QRectF& rect = labelItem->boundingRect();
QPointF center = rect.center();
labelItem->setTransformOriginPoint(center.x(), center.y());
- labelItem->setPos(m_rect.left() - rect.width() - label_padding , layout[i]-center.y());
+ labelItem->setPos( chartRect.left() - rect.width() - label_padding , layout[i]-center.y());
- if(labelItem->pos().y()+rect.height()>height) {
+ if(labelItem->pos().y() + rect.height() > height ||
+ labelItem->pos().y() < m_rect.top()) {
labelItem->setVisible(false);
lineItem->setVisible(false);
- }
- else {
+ }else{
labelItem->setVisible(true);
lineItem->setVisible(true);
height=labelItem->pos().y();
}
- m_minWidth=qMax(rect.width()+label_padding,m_minWidth);
- m_minHeight+=rect.height();
-
if ((i+1)%2 && i>1) {
QGraphicsRectItem *rectItem = static_cast<QGraphicsRectItem*>(shades.at(i/2-1));
- rectItem->setRect(m_rect.left(),layout[i],m_rect.width(),layout[i-1]-layout[i]);
+ rectItem->setRect( chartRect.left(),layout[i], chartRect.width(),layout[i-1]-layout[i]);
}
lineItem = static_cast<QGraphicsLineItem*>(axis.at(i+1));
- lineItem->setLine(m_rect.left()-5,layout[i],m_rect.left(),layout[i]);
+ lineItem->setLine( chartRect.left()-5,layout[i], chartRect.left(),layout[i]);
}
-
}
void ChartValueAxisY::handleAxisUpdated()
@@ -123,5 +133,43 @@ void ChartValueAxisY::handleAxisUpdated()
ChartAxis::handleAxisUpdated();
}
+QSizeF ChartValueAxisY::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
+{
+ Q_UNUSED(constraint)
+
+ QFontMetrics fn(m_font);
+ QSizeF sh;
+ QSizeF base = ChartAxis::sizeHint(which, constraint);
+ QStringList ticksList = createNumberLabels(m_min,m_max,m_tickCount);
+ qreal width=0;
+ qreal height=0;
+
+ switch (which) {
+ case Qt::MinimumSize: {
+ int count = qMax(ticksList.first().count() , ticksList.last().count());
+ width=fn.averageCharWidth()*count+label_padding;
+ height=fn.height();
+ height=qMax(height,base.height());
+ width+=base.width();
+ sh = QSizeF(width,height);
+ break;
+ }
+ case Qt::PreferredSize:
+ {
+ for (int i = 0; i < ticksList.size(); ++i)
+ {
+ width=qMax(qreal(fn.averageCharWidth()*ticksList.at(i).count())+label_padding,width);
+ height+=fn.height();
+ }
+ height=qMax(height,base.height());
+ width+=base.width();
+ sh = QSizeF(width,height);
+ break;
+ }
+ default:
+ break;
+ }
+ return sh;
+}
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/axis/valueaxis/chartvalueaxisy_p.h b/src/axis/valueaxis/chartvalueaxisy_p.h
index 46879541..1c099f74 100644
--- a/src/axis/valueaxis/chartvalueaxisy_p.h
+++ b/src/axis/valueaxis/chartvalueaxisy_p.h
@@ -44,7 +44,7 @@ public:
~ChartValueAxisY();
AxisType axisType() const { return Y_AXIS;}
-
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF& constraint) const;
protected:
QVector<qreal> calculateLayout() const;
void updateGeometry();
diff --git a/src/chartbackground_p.h b/src/chartbackground_p.h
index 7e97e36c..0a517530 100644
--- a/src/chartbackground_p.h
+++ b/src/chartbackground_p.h
@@ -50,7 +50,6 @@ public:
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
-
private:
int roundness(qreal size) const;
diff --git a/src/chartlayout.cpp b/src/chartlayout.cpp
index 176a0a82..b145518f 100644
--- a/src/chartlayout.cpp
+++ b/src/chartlayout.cpp
@@ -22,17 +22,20 @@
#include "chartpresenter_p.h"
#include "qlegend_p.h"
#include "chartaxis_p.h"
+#include "charttitle_p.h"
+#include "chartbackground_p.h"
+#include "layoutdebuger_p.h"
+#include "legendmarker_p.h"
#include <QDebug>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
+static const qreal golden_ratio = 0.25;
+
ChartLayout::ChartLayout(ChartPresenter* presenter):
m_presenter(presenter),
-m_marginBig(60),
-m_marginSmall(20),
-m_marginTiny(10),
-m_chartMargins(m_marginBig,m_marginBig,m_marginBig,m_marginBig),
-m_intialized(false)
+m_margins(20,20,20,20),
+m_minChartRect(0,0,200,200)
{
}
@@ -44,137 +47,213 @@ ChartLayout::~ChartLayout()
void ChartLayout::setGeometry(const QRectF& rect)
{
+ Q_ASSERT(rect.isValid());
- if (!rect.isValid()) return;
+ QList<ChartAxis*> axes = m_presenter->axisItems();
+ ChartTitle* title = m_presenter->titleElement();
+ QLegend* legend = m_presenter->legend();
+ ChartBackground* background = m_presenter->backgroundElement();
- QGraphicsLayout::setGeometry(rect);
+ QRectF contentGeometry = calculateBackgroundGeometry(rect,background);
- if(!m_intialized){
- m_presenter->setGeometry(rect);
- m_intialized=true;
- }
+ contentGeometry = calculateContentGeometry(contentGeometry);
- // check title size
+ if (title && title->isVisible()) {
+ contentGeometry = calculateTitleGeometry(contentGeometry,title);
+ }
- QSize titleSize = QSize(0,0);
+ if (legend->isAttachedToChart() && legend->isVisible()) {
+ contentGeometry = calculateLegendGeometry(contentGeometry,legend);
+ }
- if (m_presenter->titleItem()) {
- titleSize= m_presenter->titleItem()->boundingRect().size().toSize();
+ calculateChartGeometry(contentGeometry,axes);
+
+ //TODO remove me
+#ifdef SHOW_LAYOUT
+ LayoutDebuger* debuger = LayoutDebuger::instance();
+ debuger->reset();
+ debuger->setPen(QPen(Qt::red));
+ debuger->add(backgroundGeometry,m_presenter->rootItem());
+ debuger->add(titleGeometry,m_presenter->rootItem());
+ debuger->add(legendGeometry ,m_presenter->rootItem());
+ debuger->add(axisGeometry ,m_presenter->rootItem());
+ debuger->add(geometry,m_presenter->rootItem());
+ foreach(LegendMarker* marker,legend->d_ptr->markers()){
+ debuger->add(marker->mapRectToScene(marker->boundingRect()),m_presenter->rootItem());
}
+#endif
+
+ QGraphicsLayout::setGeometry(rect);
+}
+
+QRectF ChartLayout::calculateContentGeometry(const QRectF& geometry) const
+{
+ return geometry.adjusted(m_margins.left(),m_margins.top(),-m_margins.right(),-m_margins.bottom());
+}
+
+QRectF ChartLayout::calculateContentMinimum(const QRectF& minimum) const
+{
+ return minimum.adjusted(0,0,m_margins.left()+m_margins.right(),m_margins.top() + m_margins.bottom());
+}
- qreal axisHeight = 0;
- qreal axisWidth = 0;
+
+QRectF ChartLayout::calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const
+{
+ qreal left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ QRectF backgroundGeometry = geometry.adjusted(left,top,-right,-bottom);
+ if(background) background->setRect(backgroundGeometry);
+ return backgroundGeometry;
+}
+
+QRectF ChartLayout::calculateBackgroundMinimum(const QRectF& minimum) const
+{
+ qreal left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ return minimum.adjusted(0,0,left + right,top+bottom);
+}
+
+QRectF ChartLayout::calculateChartGeometry(const QRectF& geometry, const QList<ChartAxis*>& axes) const
+{
+
+ QSizeF vertical(0,0);
+ QSizeF horizontal(0,0);
// check axis size
+ foreach(ChartAxis* axis , axes) {
+ if(axis->orientation()==Qt::Vertical && axis->isVisible()) {
+ vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
+ }
+ else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
+ horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
+ }
- foreach (ChartAxis* axis,m_presenter->axisItems()){
- if(axis->axisType() == ChartAxis::X_AXIS)
- axisHeight = qMax(axis->minimumHeight(),axisHeight);
- else
- axisWidth = qMax(axis->minimumWidth(),axisWidth);
}
- QLegend* legend = m_presenter->legend();
- Q_ASSERT(legend);
+ qreal width = qMin(vertical.width(),geometry.width() * golden_ratio);
- qreal titlePadding = m_chartMargins.top()/2;
+ QRectF rect = geometry.adjusted(width,vertical.height()/2,-horizontal.width()/2,-horizontal.height());
- QMargins chartMargins = m_chartMargins;
+ m_presenter->setChartsGeometry(rect);
- //TODO multiple axis handling;
- chartMargins.setLeft(qMax(m_chartMargins.left(),int(axisWidth + 2*m_marginTiny)));
- chartMargins.setBottom(qMax(m_chartMargins.bottom(),int(axisHeight + 2* m_marginTiny)));
+ foreach(ChartAxis* axis , axes) {
+ axis->setGeometry(geometry);
+ }
+ return rect;
+}
- // recalculate legend position
- if ((legend->isAttachedToChart() && legend->isVisible())) {
+QRectF ChartLayout::calculateAxisMinimum(const QRectF& minimum, const QList<ChartAxis*>& axes) const
+{
+ QSizeF vertical(0,0);
+ QSizeF horizontal(0,0);
- // Reserve some space for legend
- switch (legend->alignment()) {
+ // check axis size
+ foreach(ChartAxis* axis , axes) {
+ if(axis->orientation()==Qt::Vertical && axis->isVisible()){
+ vertical = vertical.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
+ }else if(axis->orientation()==Qt::Horizontal && axis->isVisible()) {
+ horizontal = horizontal.expandedTo(axis->effectiveSizeHint(Qt::MinimumSize));
+ }
+ }
+ return minimum.adjusted(0,0,horizontal.width()+vertical.width(),horizontal.height() + vertical.height());
+}
- case Qt::AlignTop: {
+QRectF ChartLayout::calculateLegendGeometry(const QRectF& geometry,QLegend* legend) const
+{
+ QSizeF size = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,-1));
+ QRectF legendRect;
+ QRectF result;
- QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
- int topMargin = 2*m_marginTiny + titleSize.height() + legendSize.height() + m_marginTiny;
- chartMargins = QMargins(chartMargins.left(),topMargin,chartMargins.right(),chartMargins.bottom());
- m_legendMargins = QMargins(chartMargins.left(),topMargin - (legendSize.height() + m_marginTiny),chartMargins.right(),rect.height()-topMargin + m_marginTiny);
- titlePadding = m_marginTiny + m_marginTiny;
+ switch (legend->alignment()) {
+
+ case Qt::AlignTop: {
+ legendRect = QRectF(geometry.topLeft(),QSizeF(geometry.width(),size.height()));
+ result = geometry.adjusted(0,legendRect.height(),0,0);
break;
}
case Qt::AlignBottom: {
- QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(rect.width(),-1));
- int bottomMargin = m_marginTiny + legendSize.height() + m_marginTiny + axisHeight;
- chartMargins = QMargins(chartMargins.left(),chartMargins.top(),chartMargins.right(),bottomMargin);
- m_legendMargins = QMargins(chartMargins.left(),rect.height()-bottomMargin + m_marginTiny + axisHeight,chartMargins.right(),m_marginTiny + m_marginSmall);
- titlePadding = chartMargins.top()/2;
+ legendRect = QRectF(QPointF(geometry.left(),geometry.bottom()-size.height()),QSizeF(geometry.width(),size.height()));
+ result = geometry.adjusted(0,0,0,-legendRect.height());
break;
}
case Qt::AlignLeft: {
- QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
- int leftPadding = m_marginTiny + legendSize.width() + m_marginTiny + axisWidth;
- chartMargins = QMargins(leftPadding,chartMargins.top(),chartMargins.right(),chartMargins.bottom());
- m_legendMargins = QMargins(m_marginTiny + m_marginSmall,chartMargins.top(),rect.width()-leftPadding + m_marginTiny + axisWidth,chartMargins.bottom());
- titlePadding = chartMargins.top()/2;
+ qreal width = qMin(size.width(),geometry.width()*golden_ratio);
+ legendRect = QRectF(geometry.topLeft(),QSizeF(width,geometry.height()));
+ result = geometry.adjusted(width,0,0,0);
break;
}
case Qt::AlignRight: {
- QSizeF legendSize = legend->effectiveSizeHint(Qt::PreferredSize,QSizeF(-1,rect.height()));
- int rightPadding = m_marginTiny + legendSize.width() + m_marginTiny;
- chartMargins = QMargins(chartMargins.left(),chartMargins.top(),rightPadding,chartMargins.bottom());
- m_legendMargins = QMargins(rect.width()- rightPadding+ m_marginTiny ,chartMargins.top(),m_marginTiny + m_marginSmall,chartMargins.bottom());
- titlePadding = chartMargins.top()/2;
+ qreal width = qMin(size.width(),geometry.width()*golden_ratio);
+ legendRect = QRectF(QPointF(geometry.right()-width,geometry.top()),QSizeF(width,geometry.height()));
+ result = geometry.adjusted(0,0,-width,0);
break;
}
default: {
break;
}
- }
-
- legend->setGeometry(rect.adjusted(m_legendMargins.left(),m_legendMargins.top(),-m_legendMargins.right(),-m_legendMargins.bottom()));
}
- // recalculate title position
- if (m_presenter->titleItem()) {
- QPointF center = rect.center() - m_presenter->titleItem()->boundingRect().center();
- m_presenter->titleItem()->setPos(center.x(),titlePadding);
- }
+ legend->setGeometry(legendRect);
- //recalculate background gradient
- if (m_presenter->backgroundItem()) {
- m_presenter->backgroundItem()->setRect(rect.adjusted(m_marginTiny,m_marginTiny, -m_marginTiny, -m_marginTiny));
- }
+ return result;
+}
- QRectF chartRect = rect.adjusted(chartMargins.left(),chartMargins.top(),-chartMargins.right(),-chartMargins.bottom());
+QRectF ChartLayout::calculateLegendMinimum(const QRectF& geometry,QLegend* legend) const
+{
+ QSizeF minSize = legend->effectiveSizeHint(Qt::MinimumSize,QSizeF(-1,-1));
+ return geometry.adjusted(0,0,minSize.width(),minSize.height());
+}
- if(m_presenter->geometry()!=chartRect && chartRect.isValid()){
- m_presenter->setGeometry(chartRect);
- }else if(chartRect.size().isEmpty()){
- m_presenter->setGeometry(QRect(rect.width()/2,rect.height()/2,1,1));
- }
+QRectF ChartLayout::calculateTitleGeometry(const QRectF& geometry,ChartTitle* title) const
+{
+ title->setGeometry(geometry);
+ QPointF center = geometry.center() - title->boundingRect().center();
+ title->setPos(center.x(),title->pos().y());
+ return geometry.adjusted(0,title->boundingRect().height(),0,0);
}
+QRectF ChartLayout::calculateTitleMinimum(const QRectF& minimum,ChartTitle* title) const
+{
+ QSizeF min = title->sizeHint(Qt::MinimumSize);
+ return minimum.adjusted(0,0,min.width(),min.height());
+}
QSizeF ChartLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
{
Q_UNUSED(constraint);
- if(which == Qt::MinimumSize)
- return QSize(2*(m_chartMargins.top()+m_chartMargins.bottom()),2*(m_chartMargins.top() + m_chartMargins.bottom()));
- else
+ if(which == Qt::MinimumSize){
+ QList<ChartAxis*> axes = m_presenter->axisItems();
+ ChartTitle* title = m_presenter->titleElement();
+ QLegend* legend = m_presenter->legend();
+ QRectF minimumRect(0,0,0,0);
+ minimumRect = calculateBackgroundMinimum(minimumRect);
+ minimumRect = calculateContentMinimum(minimumRect);
+ minimumRect = calculateTitleMinimum(minimumRect,title);
+ minimumRect = calculateLegendMinimum(minimumRect,legend);
+ minimumRect = calculateAxisMinimum(minimumRect,axes);
+ return minimumRect.united(m_minChartRect).size().toSize();
+ }else
return QSize(-1,-1);
}
-void ChartLayout::setMinimumMargins(const QMargins& margins)
+void ChartLayout::setMargins(const QMargins& margins)
{
- if(m_chartMargins != margins){
- m_chartMargins = margins;
+ if(m_margins != margins){
+ m_margins = margins;
updateGeometry();
}
}
-QMargins ChartLayout::minimumMargins() const
+QMargins ChartLayout::margins() const
+{
+ return m_margins;
+}
+
+void ChartLayout::adjustChartGeometry()
{
- return m_chartMargins;
+ setGeometry(geometry());
}
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/chartlayout_p.h b/src/chartlayout_p.h
index 0785d222..ff3c6349 100644
--- a/src/chartlayout_p.h
+++ b/src/chartlayout_p.h
@@ -27,6 +27,10 @@
QTCOMMERCIALCHART_BEGIN_NAMESPACE
class ChartPresenter;
+class ChartTitle;
+class QLegend;
+class ChartAxis;
+class ChartBackground;
class ChartLayout : public QGraphicsLayout
{
@@ -35,10 +39,11 @@ public:
ChartLayout(ChartPresenter* presenter);
virtual ~ChartLayout();
- void setMinimumMargins(const QMargins& margins);
- QMargins minimumMargins() const;
+ void setMargins(const QMargins& margins);
+ QMargins margins() const;
void setGeometry(const QRectF& rect);
+ void adjustChartGeometry();
protected:
QSizeF sizeHint ( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const;
@@ -47,15 +52,22 @@ protected:
void removeAt(int){};
private:
- ChartPresenter* m_presenter;
- int m_marginBig;
- int m_marginSmall;
- int m_marginTiny;
- QMargins m_chartMargins;
- QMargins m_legendMargins;
- bool m_intialized;
-
+ QRectF calculateBackgroundGeometry(const QRectF& geometry,ChartBackground* background) const;
+ QRectF calculateContentGeometry(const QRectF& geometry) const;
+ QRectF calculateTitleGeometry(const QRectF& geometry, ChartTitle* title) const;
+ QRectF calculateChartGeometry(const QRectF& geometry,const QList<ChartAxis*>& axes) const;
+ QRectF calculateLegendGeometry(const QRectF& geometry, QLegend* legend) const;
+ QRectF calculateBackgroundMinimum(const QRectF& minimum) const;
+ QRectF calculateContentMinimum(const QRectF& minimum) const;
+ QRectF calculateTitleMinimum(const QRectF& minimum,ChartTitle* title) const;
+ QRectF calculateAxisMinimum(const QRectF& minimum,const QList<ChartAxis*>& axes) const;
+ QRectF calculateLegendMinimum(const QRectF& minimum,QLegend* legend) const;
+private:
+ ChartPresenter* m_presenter;
+ QMargins m_margins;
+ QRectF m_minChartRect;
+ QRectF m_minAxisRect;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/chartpresenter.cpp b/src/chartpresenter.cpp
index 3554b634..4e51b84d 100644
--- a/src/chartpresenter.cpp
+++ b/src/chartpresenter.cpp
@@ -28,11 +28,9 @@
#include "qabstractseries_p.h"
#include "qareaseries.h"
#include "chartaxis_p.h"
-//#include "chartaxisx_p.h"
-//#include "chartaxisy_p.h"
-#include "areachartitem_p.h"
#include "chartbackground_p.h"
#include "chartlayout_p.h"
+#include "charttitle_p.h"
#include <QTimer>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -44,8 +42,8 @@ m_chartTheme(0),
m_options(QChart::NoAnimation),
m_state(ShowState),
m_layout(new ChartLayout(this)),
-m_backgroundItem(0),
-m_titleItem(0)
+m_background(0),
+m_title(0)
{
}
@@ -55,17 +53,24 @@ ChartPresenter::~ChartPresenter()
delete m_chartTheme;
}
-void ChartPresenter::setGeometry(const QRectF& rect)
+void ChartPresenter::setChartsGeometry(const QRectF& rect)
{
-
Q_ASSERT(rect.isValid());
- if(m_rect!=rect) {
- m_rect=rect;
- emit geometryChanged(m_rect);
+ if(m_chartsRect!=rect) {
+ m_chartsRect=rect;
+ foreach(ChartElement* chart, m_chartItems)
+ {
+ chart->handleGeometryChanged(rect);
+ }
}
}
+QRectF ChartPresenter::chartsGeometry() const
+{
+ return m_chartsRect;
+}
+
void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
{
ChartAxis* item = axis->d_ptr->createGraphics(this);
@@ -84,7 +89,7 @@ void ChartPresenter::handleAxisAdded(QAbstractAxis* axis,Domain* domain)
m_chartTheme->decorate(axis);
axis->d_ptr->setDirty(false);
axis->d_ptr->emitUpdated();
- if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
+ if(m_chartsRect.isValid()) item->handleGeometryChanged(m_chartsRect);
m_axisItems.insert(axis, item);
selectVisibleAxis();
@@ -113,7 +118,7 @@ void ChartPresenter::handleSeriesAdded(QAbstractSeries* series,Domain* domain)
//initialize
item->handleDomainUpdated();
- if(m_rect.isValid()) item->handleGeometryChanged(m_rect);
+ if(m_chartsRect.isValid()) item->handleGeometryChanged(m_chartsRect);
m_chartItems.insert(series,item);
}
@@ -222,27 +227,29 @@ void ChartPresenter::resetAllElements()
handleSeriesRemoved(series);
handleSeriesAdded(series,domain);
}
+
+ layout()->invalidate();
}
void ChartPresenter::zoomIn(qreal factor)
{
- QRectF rect = geometry();
+ QRectF rect = chartsGeometry();
rect.setWidth(rect.width()/factor);
rect.setHeight(rect.height()/factor);
- rect.moveCenter(geometry().center());
+ rect.moveCenter(chartsGeometry().center());
zoomIn(rect);
}
void ChartPresenter::zoomIn(const QRectF& rect)
{
QRectF r = rect.normalized();
- r.translate(-geometry().topLeft());
+ r.translate(-chartsGeometry().topLeft());
if (!r.isValid())
return;
m_state = ZoomInState;
- m_statePoint = QPointF(r.center().x()/geometry().width(),r.center().y()/geometry().height());
- m_dataset->zoomInDomain(r,geometry().size());
+ m_statePoint = QPointF(r.center().x()/chartsGeometry().width(),r.center().y()/chartsGeometry().height());
+ m_dataset->zoomInDomain(r,chartsGeometry().size());
m_state = ShowState;
}
@@ -251,14 +258,14 @@ void ChartPresenter::zoomOut(qreal factor)
m_state = ZoomOutState;
QRectF chartRect;
- chartRect.setSize(geometry().size());
+ chartRect.setSize(chartsGeometry().size());
QRectF rect;
rect.setSize(chartRect.size()/factor);
rect.moveCenter(chartRect.center());
if (!rect.isValid())
return;
- m_statePoint = QPointF(rect.center().x()/geometry().width(),rect.center().y()/geometry().height());
+ m_statePoint = QPointF(rect.center().x()/chartsGeometry().width(),rect.center().y()/chartsGeometry().height());
m_dataset->zoomOutDomain(rect, chartRect.size());
m_state = ShowState;
}
@@ -270,7 +277,7 @@ void ChartPresenter::scroll(qreal dx,qreal dy)
if(dy<0) m_state=ScrollUpState;
if(dy>0) m_state=ScrollDownState;
- m_dataset->scrollDomain(dx,dy,geometry().size());
+ m_dataset->scrollDomain(dx,dy,chartsGeometry().size());
m_state = ShowState;
}
@@ -281,18 +288,18 @@ QChart::AnimationOptions ChartPresenter::animationOptions() const
void ChartPresenter::createBackgroundItem()
{
- if (!m_backgroundItem) {
- m_backgroundItem = new ChartBackground(rootItem());
- m_backgroundItem->setPen(Qt::NoPen);
- m_backgroundItem->setZValue(ChartPresenter::BackgroundZValue);
+ if (!m_background) {
+ m_background = new ChartBackground(rootItem());
+ m_background->setPen(Qt::NoPen);
+ m_background->setZValue(ChartPresenter::BackgroundZValue);
}
}
void ChartPresenter::createTitleItem()
{
- if (!m_titleItem) {
- m_titleItem = new QGraphicsSimpleTextItem(rootItem());
- m_titleItem->setZValue(ChartPresenter::BackgroundZValue);
+ if (!m_title) {
+ m_title = new ChartTitle(rootItem());
+ m_title->setZValue(ChartPresenter::BackgroundZValue);
}
}
@@ -313,104 +320,94 @@ void ChartPresenter::startAnimation(ChartAnimation* animation)
QTimer::singleShot(0, animation, SLOT(start()));
}
-QGraphicsRectItem* ChartPresenter::backgroundItem()
-{
- return m_backgroundItem;
-}
-
void ChartPresenter::setBackgroundBrush(const QBrush& brush)
{
createBackgroundItem();
- m_backgroundItem->setBrush(brush);
+ m_background->setBrush(brush);
m_layout->invalidate();
}
QBrush ChartPresenter::backgroundBrush() const
{
- if (!m_backgroundItem) return QBrush();
- return m_backgroundItem->brush();
+ if (!m_background) return QBrush();
+ return m_background->brush();
}
void ChartPresenter::setBackgroundPen(const QPen& pen)
{
createBackgroundItem();
- m_backgroundItem->setPen(pen);
+ m_background->setPen(pen);
m_layout->invalidate();
}
QPen ChartPresenter::backgroundPen() const
{
- if (!m_backgroundItem) return QPen();
- return m_backgroundItem->pen();
-}
-
-QGraphicsItem* ChartPresenter::titleItem()
-{
- return m_titleItem;
+ if (!m_background) return QPen();
+ return m_background->pen();
}
void ChartPresenter::setTitle(const QString& title)
{
createTitleItem();
- m_titleItem->setText(title);
+ m_title->setText(title);
m_layout->invalidate();
}
QString ChartPresenter::title() const
{
- if (!m_titleItem) return QString();
- return m_titleItem->text();
+ if (!m_title) return QString();
+ return m_title->text();
}
void ChartPresenter::setTitleFont(const QFont& font)
{
createTitleItem();
- m_titleItem->setFont(font);
+ m_title->setFont(font);
m_layout->invalidate();
}
QFont ChartPresenter::titleFont() const
{
- if (!m_titleItem) return QFont();
- return m_titleItem->font();
+ if (!m_title) return QFont();
+ return m_title->font();
}
void ChartPresenter::setTitleBrush(const QBrush &brush)
{
createTitleItem();
- m_titleItem->setBrush(brush);
+ m_title->setBrush(brush);
m_layout->invalidate();
}
QBrush ChartPresenter::titleBrush() const
{
- if (!m_titleItem) return QBrush();
- return m_titleItem->brush();
+ if (!m_title) return QBrush();
+ return m_title->brush();
}
void ChartPresenter::setBackgroundVisible(bool visible)
{
createBackgroundItem();
- m_backgroundItem->setVisible(visible);
+ m_background->setVisible(visible);
}
bool ChartPresenter::isBackgroundVisible() const
{
- if (!m_backgroundItem) return false;
- return m_backgroundItem->isVisible();
+ if (!m_background) return false;
+ return m_background->isVisible();
}
void ChartPresenter::setBackgroundDropShadowEnabled(bool enabled)
{
createBackgroundItem();
- m_backgroundItem->setDropShadowEnabled(enabled);
+ m_background->setDropShadowEnabled(enabled);
}
bool ChartPresenter::isBackgroundDropShadowEnabled() const
{
- if (!m_backgroundItem) return false;
- return m_backgroundItem->isDropShadowEnabled();
+ if (!m_background) return false;
+ return m_background->isDropShadowEnabled();
}
@@ -419,14 +416,14 @@ QGraphicsLayout* ChartPresenter::layout()
return m_layout;
}
-void ChartPresenter::setMinimumMargins(const QMargins& margins)
+void ChartPresenter::setMargins(const QMargins& margins)
{
- m_layout->setMinimumMargins(margins);
+ m_layout->setMargins(margins);
}
-QMargins ChartPresenter::minimumMargins() const
+QMargins ChartPresenter::margins() const
{
- return m_layout->minimumMargins();
+ return m_layout->margins();
}
QLegend* ChartPresenter::legend()
@@ -434,14 +431,24 @@ QLegend* ChartPresenter::legend()
return m_chart->legend();
}
+void ChartPresenter::setVisible(bool visible)
+{
+ m_chart->setVisible(visible);
+}
+
+ChartBackground* ChartPresenter::backgroundElement()
+{
+ return m_background;
+}
+
QList<ChartAxis*> ChartPresenter::axisItems() const
{
return m_axisItems.values();
}
-void ChartPresenter::setVisible(bool visible)
+ChartTitle* ChartPresenter::titleElement()
{
- m_chart->setVisible(visible);
+ return m_title;
}
#include "moc_chartpresenter_p.cpp"
diff --git a/src/chartpresenter_p.h b/src/chartpresenter_p.h
index 7a78cfdb..a17264bd 100644
--- a/src/chartpresenter_p.h
+++ b/src/chartpresenter_p.h
@@ -45,6 +45,7 @@ class ChartAxis;
class ChartTheme;
class ChartAnimator;
class ChartBackground;
+class ChartTitle;
class ChartAnimation;
class ChartLayout;
@@ -83,8 +84,8 @@ public:
ChartTheme *chartTheme() const { return m_chartTheme; }
ChartDataSet *dataSet() const { return m_dataset; }
QGraphicsItem* rootItem() const { return m_chart; }
- QGraphicsRectItem* backgroundItem();
- QGraphicsItem* titleItem();
+ ChartBackground* backgroundElement();
+ ChartTitle* titleElement();
QList<ChartAxis*> axisItems() const;
QLegend* legend();
@@ -123,8 +124,8 @@ public:
void zoomOut(qreal factor);
void scroll(qreal dx,qreal dy);
- void setGeometry(const QRectF& rect);
- QRectF geometry() { return m_rect; }
+ void setChartsGeometry(const QRectF& rect);
+ QRectF chartsGeometry() const;
void startAnimation(ChartAnimation* animation);
State state() const { return m_state; }
@@ -132,8 +133,8 @@ public:
void resetAllElements();
- void setMinimumMargins(const QMargins& margins);
- QMargins minimumMargins() const;
+ void setMargins(const QMargins& margins);
+ QMargins margins() const;
QGraphicsLayout* layout();
private:
@@ -162,14 +163,14 @@ private:
ChartTheme *m_chartTheme;
QMap<QAbstractSeries*, ChartElement*> m_chartItems;
QMap<QAbstractAxis*, ChartAxis*> m_axisItems;
- QRectF m_rect;
+ QRectF m_chartsRect;
QChart::AnimationOptions m_options;
State m_state;
QPointF m_statePoint;
QList<ChartAnimation*> m_animations;
ChartLayout* m_layout;
- ChartBackground* m_backgroundItem;
- QGraphicsSimpleTextItem* m_titleItem;
+ ChartBackground* m_background;
+ ChartTitle* m_title;
};
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/charttitle.cpp b/src/charttitle.cpp
new file mode 100644
index 00000000..816bdbf6
--- /dev/null
+++ b/src/charttitle.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "charttitle_p.h"
+#include <QFont>
+#include <QFontMetrics>
+#include <QDebug>
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+ChartTitle::ChartTitle(QGraphicsItem* parent):QGraphicsSimpleTextItem(parent)
+{
+
+}
+
+ChartTitle::~ChartTitle()
+{
+
+}
+
+void ChartTitle::setText(const QString &text)
+{
+ m_text=text;
+}
+
+QString ChartTitle::text() const
+{
+ return m_text;
+}
+
+void ChartTitle::setGeometry(const QRectF &rect)
+{
+ QFontMetrics fn(font());
+
+ int width = rect.width();
+
+ if (fn.boundingRect(m_text).width() > width)
+ {
+ QString string = m_text + "...";
+ while (fn.boundingRect(string).width() > width && string.length() > 3)
+ string.remove(string.length() - 4, 1);
+ QGraphicsSimpleTextItem::setText(string);
+ }
+ else
+ QGraphicsSimpleTextItem::setText(m_text);
+
+ setPos(rect.topLeft());
+}
+
+
+QSizeF ChartTitle::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+ Q_UNUSED(constraint);
+ QFontMetrics fn (font ());
+ QSizeF sh;
+
+ switch(which) {
+ case Qt::MinimumSize:
+ sh = QSizeF(fn.boundingRect ("...").width(),fn.height());
+ break;
+ case Qt::PreferredSize:
+ sh = QSizeF(fn.boundingRect(m_text).width(),fn.height());
+ break;
+ case Qt::MaximumSize:
+ sh = QSizeF(fn.boundingRect(m_text).width(),fn.height());
+ break;
+ case Qt::MinimumDescent:
+ sh = QSizeF(0, fn.descent ());
+ break;
+ default:
+ break;
+ }
+
+ return sh;
+}
+
+QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/charttitle_p.h b/src/charttitle_p.h
new file mode 100644
index 00000000..9c9bf514
--- /dev/null
+++ b/src/charttitle_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt Commercial Charts Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtCommercial Chart API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef CHARTTITLE_P_H_
+#define CHARTTITLE_P_H_
+
+#include "qchartglobal.h"
+#include <QGraphicsSimpleTextItem>
+
+QTCOMMERCIALCHART_BEGIN_NAMESPACE
+
+class ChartTitle : public QGraphicsSimpleTextItem
+{
+public:
+ ChartTitle(QGraphicsItem* parent = 0);
+ ~ChartTitle();
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+ void setText(const QString &text);
+ QString text() const;
+ void setGeometry(const QRectF &rect);
+private:
+ QString m_text;
+};
+
+QTCOMMERCIALCHART_END_NAMESPACE
+
+#endif /* CHARTTITLE_P_H_ */
diff --git a/src/domain.cpp b/src/domain.cpp
index be38098d..84d6183e 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -178,7 +178,6 @@ void Domain::handleAxisUpdated()
}else if(axis->orientation()==Qt::Vertical){
setRangeY(axis->min(),axis->max());
}
-
}
bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const Domain &domain1, const Domain &domain2)
diff --git a/src/legend/legendlayout.cpp b/src/legend/legendlayout.cpp
index 3a181f75..bd3a3325 100644
--- a/src/legend/legendlayout.cpp
+++ b/src/legend/legendlayout.cpp
@@ -22,6 +22,7 @@
#include "chartpresenter_p.h"
#include "legendmarker_p.h"
#include "qlegend_p.h"
+#include <QDebug>
QTCOMMERCIALCHART_BEGIN_NAMESPACE
@@ -58,6 +59,9 @@ void LegendLayout::setOffset(qreal x, qreal y)
}
QRectF boundingRect = geometry();
+ qreal left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ boundingRect.adjust(left,top,-right,-bottom);
// Limit offset between m_minOffset and m_maxOffset
if (scrollHorizontal) {
@@ -112,16 +116,20 @@ void LegendLayout::setAttachedGeometry(const QRectF& rect)
m_width=0;
m_height=0;
+ qreal left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+
+ QRectF geometry = rect.adjusted(left,top,-right,-bottom);
+
switch(m_legend->alignment()) {
case Qt::AlignTop:
-
case Qt::AlignBottom: {
QPointF point(0,0);
foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
- marker->setPos(point.x(),rect.height()/2 - marker->boundingRect().height()/2);
+ marker->setGeometry(geometry);
+ marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
const QRectF& rect = marker->boundingRect();
size = size.expandedTo(rect.size());
qreal w = rect.width();
@@ -129,12 +137,12 @@ void LegendLayout::setAttachedGeometry(const QRectF& rect)
point.setX(point.x() + w);
}
}
- if(m_width<rect.width()) {
- m_legend->d_ptr->items()->setPos(rect.width()/2-m_width/2,rect.top());
+ if(m_width<geometry.width()) {
+ m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
}
else {
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
}
m_height=size.height();
}
@@ -144,7 +152,7 @@ void LegendLayout::setAttachedGeometry(const QRectF& rect)
QPointF point(0,0);
foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
+ marker->setGeometry(geometry);
marker->setPos(point);
const QRectF& rect = marker->boundingRect();
qreal h = rect.height();
@@ -153,21 +161,22 @@ void LegendLayout::setAttachedGeometry(const QRectF& rect)
point.setY(point.y() + h);
}
}
- if(m_height<rect.height()) {
- m_legend->d_ptr->items()->setPos(rect.left(),rect.height()/2-m_height/2);
+ if(m_height<geometry.height()) {
+ m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
}
else {
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
}
m_width=size.width();
}
break;
}
- m_minOffsetX = 0;
- m_minOffsetY = 0;
- m_maxOffsetX = m_width - rect.width();
- m_maxOffsetY = m_height - rect.height();
+
+ m_minOffsetX = -left;
+ m_minOffsetY = - top;
+ m_maxOffsetX = m_width - geometry.width() - right;
+ m_maxOffsetY = m_height - geometry.height() - bottom;
}
void LegendLayout::setDettachedGeometry(const QRectF& rect)
@@ -182,6 +191,10 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
m_offsetX=0;
m_offsetY=0;
+ qreal left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ QRectF geometry = rect.adjusted(left,top,-right,-bottom);
+
QSizeF size(0,0);
QList<LegendMarker *> markers = m_legend->d_ptr->markers();
@@ -190,13 +203,13 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
switch (m_legend->alignment()) {
case Qt::AlignTop: {
- QPointF point = rect.topLeft();
+ QPointF point(0,0);
m_width = 0;
m_height = 0;
for (int i=0; i<markers.count(); i++) {
LegendMarker *marker = markers.at(i);
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
+ marker->setGeometry(geometry);
marker->setPos(point.x(),point.y());
const QRectF& boundingRect = marker->boundingRect();
qreal w = boundingRect.width();
@@ -204,9 +217,9 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
m_width = qMax(m_width,w);
m_height = qMax(m_height,h);
point.setX(point.x() + w);
- if (point.x() + w > rect.topLeft().x() + rect.width()) {
+ if (point.x() + w > geometry.left() + geometry.width() - right) {
// Next item would go off rect.
- point.setX(rect.topLeft().x());
+ point.setX(0);
point.setY(point.y() + h);
if (i+1 < markers.count()) {
m_height += h;
@@ -214,22 +227,22 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
}
}
}
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_minOffsetX = 0;
- m_minOffsetY = 0;
- m_maxOffsetX = m_width - rect.width();
- m_maxOffsetY = m_height - rect.height();
+ m_minOffsetX = -left;
+ m_minOffsetY = -top;
+ m_maxOffsetX = m_width - geometry.width() - right;
+ m_maxOffsetY = m_height - geometry.height() - bottom;
}
break;
case Qt::AlignBottom: {
- QPointF point = rect.bottomLeft();
+ QPointF point(0,geometry.height());
m_width = 0;
m_height = 0;
for (int i=0; i<markers.count(); i++) {
LegendMarker *marker = markers.at(i);
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
+ marker->setGeometry(geometry);
const QRectF& boundingRect = marker->boundingRect();
qreal w = boundingRect.width();
qreal h = boundingRect.height();
@@ -237,9 +250,9 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
m_height = qMax(m_height,h);
marker->setPos(point.x(),point.y() - h);
point.setX(point.x() + w);
- if (point.x() + w > rect.bottomLeft().x() + rect.width()) {
+ if (point.x() + w > geometry.left() + geometry.width() - right) {
// Next item would go off rect.
- point.setX(rect.bottomLeft().x());
+ point.setX(0);
point.setY(point.y() - h);
if (i+1 < markers.count()) {
m_height += h;
@@ -247,23 +260,23 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
}
}
}
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_minOffsetX = 0;
- m_minOffsetY = qMin(rect.topLeft().y(), rect.topLeft().y() - m_height + rect.height());
- m_maxOffsetX = m_width - rect.width();
- m_maxOffsetY = 0;
+ m_minOffsetX = -left;
+ m_minOffsetY = -m_height + geometry.height() - top;
+ m_maxOffsetX = m_width - geometry.width() - right;
+ m_maxOffsetY = -bottom;
}
break;
case Qt::AlignLeft: {
- QPointF point = rect.topLeft();
+ QPointF point(0,0);
m_width = 0;
m_height = 0;
qreal maxWidth = 0;
for (int i=0; i<markers.count(); i++) {
LegendMarker *marker = markers.at(i);
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
+ marker->setGeometry(geometry);
const QRectF& boundingRect = marker->boundingRect();
qreal w = boundingRect.width();
qreal h = boundingRect.height();
@@ -271,10 +284,10 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
maxWidth = qMax(maxWidth,w);
marker->setPos(point.x(),point.y());
point.setY(point.y() + h);
- if (point.y() + h > rect.topLeft().y() + rect.height()) {
+ if (point.y() + h > geometry.bottom() - bottom) {
// Next item would go off rect.
point.setX(point.x() + maxWidth);
- point.setY(rect.topLeft().y());
+ point.setY(0);
if (i+1 < markers.count()) {
m_width += maxWidth;
maxWidth = 0;
@@ -283,23 +296,23 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
}
}
m_width += maxWidth;
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_minOffsetX = 0;
- m_minOffsetY = 0;
- m_maxOffsetX = m_width - rect.width();
- m_maxOffsetY = m_height - rect.height();
+ m_minOffsetX = -left;
+ m_minOffsetY = -top;
+ m_maxOffsetX = m_width - geometry.width() - right;
+ m_maxOffsetY = m_height - geometry.height() - bottom;
}
break;
case Qt::AlignRight: {
- QPointF point = rect.topRight();
+ QPointF point(geometry.width(),0);
m_width = 0;
m_height = 0;
qreal maxWidth = 0;
for (int i=0; i<markers.count(); i++) {
LegendMarker *marker = markers.at(i);
if (marker->isVisible()) {
- marker->setGeometry(QRectF(QPointF(0,0),marker->effectiveSizeHint(Qt::PreferredSize)));
+ marker->setGeometry(geometry);
const QRectF& boundingRect = marker->boundingRect();
qreal w = boundingRect.width();
qreal h = boundingRect.height();
@@ -307,10 +320,10 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
maxWidth = qMax(maxWidth,w);
marker->setPos(point.x() - w,point.y());
point.setY(point.y() + h);
- if (point.y() + h > rect.topLeft().y() + rect.height()) {
+ if (point.y() + h > geometry.bottom()-bottom) {
// Next item would go off rect.
point.setX(point.x() - maxWidth);
- point.setY(rect.topLeft().y());
+ point.setY(0);
if (i+1 < markers.count()) {
m_width += maxWidth;
maxWidth = 0;
@@ -319,12 +332,12 @@ void LegendLayout::setDettachedGeometry(const QRectF& rect)
}
}
m_width += maxWidth;
- m_legend->d_ptr->items()->setPos(rect.topLeft());
+ m_legend->d_ptr->items()->setPos(geometry.topLeft());
- m_minOffsetX = qMin(rect.topLeft().x(), rect.topLeft().x() - m_width + rect.width());
- m_minOffsetY = 0;
- m_maxOffsetX = 0;
- m_maxOffsetY = m_height - rect.height();
+ m_minOffsetX = - m_width + geometry.width() - left;
+ m_minOffsetY = -top;
+ m_maxOffsetX = - right;
+ m_maxOffsetY = m_height - geometry.height() - bottom;
}
break;
default:
@@ -339,8 +352,6 @@ QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) c
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
- if(which!=Qt::PreferredSize) return QSizeF(-1,-1);
-
if(constraint.isValid()) {
foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
size = size.expandedTo(marker->effectiveSizeHint(which));
@@ -372,10 +383,7 @@ QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) c
}
}
size += QSize(left + right, top + bottom);
-
return size;
-
-
}
QTCOMMERCIALCHART_END_NAMESPACE
diff --git a/src/legend/legendmarker.cpp b/src/legend/legendmarker.cpp
index e6c370f8..6857a209 100644
--- a/src/legend/legendmarker.cpp
+++ b/src/legend/legendmarker.cpp
@@ -44,7 +44,7 @@ LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
m_legend(legend),
m_textItem(new QGraphicsSimpleTextItem(this)),
m_rectItem(new QGraphicsRectItem(this)),
- m_margin(2),
+ m_margin(4),
m_space(4)
{
//setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
@@ -86,12 +86,13 @@ QFont LegendMarker::font() const
void LegendMarker::setLabel(const QString label)
{
- m_textItem->setText(label);
+ m_text = label;
+ updateGeometry();
}
QString LegendMarker::label() const
{
- return m_textItem->text();
+ return m_text;
}
QRectF LegendMarker::boundingRect() const
@@ -112,14 +113,31 @@ QBrush LegendMarker::labelBrush() const
void LegendMarker::setGeometry(const QRectF& rect)
{
+ QFontMetrics fn (font());
+
+ int width = rect.width();
+ qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
+ qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
+
+ if (fn.boundingRect(m_text).width() + x > width)
+ {
+ QString string = m_text + "...";
+ while(fn.boundingRect(string).width() + x > width && string.length() > 3)
+ string.remove(string.length() - 4, 1);
+ m_textItem->setText(string);
+ }
+ else
+ m_textItem->setText(m_text);
+
const QRectF& textRect = m_textItem->boundingRect();
- m_textItem->setPos(m_markerRect.width() + m_space + m_margin,rect.height()/2 - textRect.height()/2);
+
+ m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
m_rectItem->setRect(m_markerRect);
- m_rectItem->setPos(m_margin,rect.height()/2 - m_markerRect.height()/2);
+ m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
prepareGeometryChange();
- m_boundingRect = rect;
+ m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
}
void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
@@ -129,7 +147,6 @@ void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
Q_UNUSED(painter)
}
-
QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
{
Q_UNUSED(constraint)
@@ -139,10 +156,10 @@ QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
switch (which) {
case Qt::MinimumSize:
- sh = QSizeF(fn.boundingRect("...").width(),fn.height());
+ sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
break;
case Qt::PreferredSize:
- sh = QSizeF(fn.boundingRect(m_textItem->text()).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
+ sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
break;
default:
break;
@@ -154,7 +171,7 @@ QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) cons
void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsObject::mousePressEvent(event);
- qDebug()<<"Not implemented"; //TODO: selected signal removed for now
+ //TODO: selected signal removed for now
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/legend/legendmarker_p.h b/src/legend/legendmarker_p.h
index 6ae225a7..462370f3 100644
--- a/src/legend/legendmarker_p.h
+++ b/src/legend/legendmarker_p.h
@@ -96,6 +96,7 @@ protected:
QGraphicsRectItem *m_rectItem;
qreal m_margin;
qreal m_space;
+ QString m_text;
};
diff --git a/src/qchart.cpp b/src/qchart.cpp
index 36fef48a..66151ce1 100644
--- a/src/qchart.cpp
+++ b/src/qchart.cpp
@@ -373,18 +373,18 @@ QLegend* QChart::legend() const
/*!
Sets the minimum \a margins between the plot area (axes) and the edge of the chart widget.
*/
-void QChart::setMinimumMargins(const QMargins& margins)
+void QChart::setMargins(const QMargins& margins)
{
- d_ptr->m_presenter->setMinimumMargins(margins);
+ d_ptr->m_presenter->setMargins(margins);
}
/*!
Returns the rect that contains information about margins (distance between chart widget edge and axes).
Individual margins can be obtained by calling left, top, right, bottom on the returned rect.
*/
-QMargins QChart::minimumMargins() const
+QMargins QChart::margins() const
{
- return d_ptr->m_presenter->minimumMargins();
+ return d_ptr->m_presenter->margins();
}
/*!
@@ -393,7 +393,7 @@ QMargins QChart::minimumMargins() const
*/
QRectF QChart::plotArea() const
{
- return d_ptr->m_presenter->geometry();
+ return d_ptr->m_presenter->chartsGeometry();
}
///*!
diff --git a/src/qchart.h b/src/qchart.h
index 136eaab9..e9a0fd56 100644
--- a/src/qchart.h
+++ b/src/qchart.h
@@ -43,7 +43,7 @@ class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsWidget
Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
Q_PROPERTY(bool dropShadowEnabled READ isDropShadowEnabled WRITE setDropShadowEnabled)
Q_PROPERTY(QChart::AnimationOptions animationOptions READ animationOptions WRITE setAnimationOptions)
- Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
+ Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
Q_ENUMS(ChartTheme)
Q_ENUMS(AnimationOption)
@@ -114,8 +114,8 @@ public:
QLegend* legend() const;
- void setMinimumMargins(const QMargins& margins);
- QMargins minimumMargins() const;
+ void setMargins(const QMargins& margins);
+ QMargins margins() const;
QRectF plotArea() const;
diff --git a/src/src.pro b/src/src.pro
index 44037049..e0490dac 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -38,7 +38,8 @@ SOURCES += \
$$PWD/chartbackground.cpp \
$$PWD/chartelement.cpp \
$$PWD/scroller.cpp \
- $$PWD/chartlayout.cpp
+ $$PWD/chartlayout.cpp \
+ $$PWD/charttitle.cpp
PRIVATE_HEADERS += \
$$PWD/chartdataset_p.h \
$$PWD/chartitem_p.h \
@@ -52,8 +53,8 @@ PRIVATE_HEADERS += \
$$PWD/qchartview_p.h \
$$PWD/scroller_p.h \
$$PWD/qabstractseries_p.h \
- $$PWD/chartlayout_p.h
-
+ $$PWD/chartlayout_p.h \
+ $$PWD/charttitle_p.h
PUBLIC_HEADERS += \
$$PWD/qchart.h \
$$PWD/qchartglobal.h \