linechartitem.cpp
210 lines
| 4.9 KiB
| text/x-c
|
CppLexer
Michal Klocek
|
r144 | #include "linechartitem_p.h" | ||
#include "qlinechartseries.h" | ||||
Michal Klocek
|
r131 | #include "chartpresenter_p.h" | ||
Michal Klocek
|
r21 | #include <QPainter> | ||
Michal Klocek
|
r144 | |||
Michal Klocek
|
r21 | |||
Tero Ahola
|
r30 | QTCOMMERCIALCHART_BEGIN_NAMESPACE | ||
Michal Klocek
|
r21 | |||
Michal Klocek
|
r150 | //TODO: optimazie : remove points which are not visible | ||
Michal Klocek
|
r144 | LineChartItem::LineChartItem(ChartPresenter* presenter, QLineChartSeries* series,QGraphicsItem *parent):ChartItem(parent), | ||
Michal Klocek
|
r131 | m_presenter(presenter), | ||
m_series(series), | ||||
m_dirtyData(false), | ||||
m_dirtyGeometry(false), | ||||
m_dirtyDomain(false) | ||||
Michal Klocek
|
r21 | { | ||
Michal Klocek
|
r185 | |||
Michal Klocek
|
r21 | } | ||
Michal Klocek
|
r144 | QRectF LineChartItem::boundingRect() const | ||
Tero Ahola
|
r103 | { | ||
Michal Klocek
|
r131 | return m_rect; | ||
Tero Ahola
|
r103 | } | ||
Michal Klocek
|
r85 | |||
Michal Klocek
|
r144 | QPainterPath LineChartItem::shape() const | ||
Michal Klocek
|
r67 | { | ||
Michal Klocek
|
r131 | return m_path; | ||
} | ||||
Michal Klocek
|
r85 | |||
Michal Klocek
|
r131 | |||
Michal Klocek
|
r144 | void LineChartItem::addPoints(const QVector<QPointF>& points) | ||
Michal Klocek
|
r131 | { | ||
m_data = points; | ||||
for(int i=0; i<m_data.size();i++){ | ||||
const QPointF& point =m_data[i]; | ||||
QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this); | ||||
Michal Klocek
|
r150 | item->setPos(point.x()-1,point.y()-1);; | ||
Michal Klocek
|
r185 | if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false); | ||
Michal Klocek
|
r131 | m_points << item; | ||
} | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::addPoint(const QPointF& point) | ||
Michal Klocek
|
r131 | { | ||
m_data << point; | ||||
QGraphicsRectItem* item = new QGraphicsRectItem(0,0,3,3,this); | ||||
Michal Klocek
|
r150 | m_clipRect.contains(point); | ||
Michal Klocek
|
r131 | item->setPos(point.x()-1,point.y()-1); | ||
Michal Klocek
|
r185 | if(!m_clipRect.contains(point) || !m_series->isPointsVisible()) item->setVisible(false); | ||
Michal Klocek
|
r131 | m_points << item; | ||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::removePoint(const QPointF& point) | ||
Michal Klocek
|
r131 | { | ||
Q_ASSERT(m_data.count() == m_points.count()); | ||||
int index = m_data.lastIndexOf(point,0); | ||||
m_data.remove(index); | ||||
delete(m_points.takeAt(index)); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::setPoint(const QPointF& oldPoint,const QPointF& newPoint) | ||
Michal Klocek
|
r131 | { | ||
Q_ASSERT(m_data.count() == m_points.count()); | ||||
int index = m_data.lastIndexOf(oldPoint,0); | ||||
if(index > -1){ | ||||
m_data.replace(index,newPoint); | ||||
QGraphicsItem* item = m_points.at(index); | ||||
item->setPos(newPoint.x()-1,newPoint.y()-1); | ||||
} | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::setPoint(int index,const QPointF& point) | ||
Michal Klocek
|
r131 | { | ||
Q_ASSERT(m_data.count() == m_points.count()); | ||||
Q_ASSERT(index>=0); | ||||
m_data.replace(index,point); | ||||
QGraphicsItem* item = m_points.at(index); | ||||
item->setPos(point.x()-1,point.y()-1); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::clear() | ||
Michal Klocek
|
r131 | { | ||
qDeleteAll(m_points); | ||||
m_points.clear(); | ||||
m_hash.clear(); | ||||
m_path = QPainterPath(); | ||||
m_rect = QRect(); | ||||
m_data.clear(); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::clearView() | ||
Michal Klocek
|
r131 | { | ||
qDeleteAll(m_points); | ||||
m_points.clear(); | ||||
m_path = QPainterPath(); | ||||
m_rect = QRect(); | ||||
m_data.clear(); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) | ||
Tero Ahola
|
r108 | { | ||
Tero Ahola
|
r213 | Q_UNUSED(widget); | ||
Michal Klocek
|
r131 | Q_UNUSED(option); | ||
Tero Ahola
|
r213 | painter->save(); | ||
Michal Klocek
|
r139 | painter->setPen(m_pen); | ||
Michal Klocek
|
r150 | painter->setClipRect(m_clipRect); | ||
Tero Ahola
|
r213 | painter->drawPath(m_path); | ||
painter->restore(); | ||||
Michal Klocek
|
r67 | } | ||
Tero Ahola
|
r108 | |||
Michal Klocek
|
r144 | void LineChartItem::calculatePoint(QPointF& point, int index, const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const | ||
Michal Klocek
|
r85 | { | ||
Michal Klocek
|
r131 | const qreal deltaX = size.width()/domain.spanX(); | ||
const qreal deltaY = size.height()/domain.spanY(); | ||||
qreal x = (series->x(index) - domain.m_minX)* deltaX; | ||||
qreal y = (series->y(index) - domain.m_minY)*-deltaY + size.height(); | ||||
point.setX(x); | ||||
point.setY(y); | ||||
Michal Klocek
|
r85 | } | ||
Michal Klocek
|
r131 | |||
Michal Klocek
|
r144 | void LineChartItem::calculatePoints(QVector<QPointF>& points, QHash<int,int>& hash,const QLineChartSeries* series,const QSizeF& size, const Domain& domain) const | ||
Michal Klocek
|
r131 | { | ||
const qreal deltaX = size.width()/domain.spanX(); | ||||
const qreal deltaY = size.height()/domain.spanY(); | ||||
for (int i = 0; i < series->count(); ++i) { | ||||
qreal x = (series->x(i) - domain.m_minX)* deltaX; | ||||
qreal y = (series->y(i) - domain.m_minY)*-deltaY + size.height(); | ||||
hash[i] = points.size(); | ||||
points << QPointF(x,y); | ||||
} | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::updateDomain() | ||
Michal Klocek
|
r131 | { | ||
clear(); | ||||
Michal Klocek
|
r150 | prepareGeometryChange(); | ||
Michal Klocek
|
r131 | calculatePoints(m_data,m_hash,m_series,m_size, m_domain); | ||
addPoints(m_data); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::updateData() | ||
Michal Klocek
|
r131 | { | ||
//for now the same | ||||
updateDomain(); | ||||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::updateGeometry() | ||
Michal Klocek
|
r67 | { | ||
Michal Klocek
|
r25 | |||
Michal Klocek
|
r131 | if(m_data.size()==0) return; | ||
Michal Klocek
|
r25 | |||
Michal Klocek
|
r131 | prepareGeometryChange(); | ||
Michal Klocek
|
r85 | QPainterPath path; | ||
Michal Klocek
|
r131 | const QPointF& point = m_data.at(0); | ||
path.moveTo(point); | ||||
Michal Klocek
|
r25 | |||
Michal Klocek
|
r131 | foreach( const QPointF& point , m_data) { | ||
path.lineTo(point); | ||||
Michal Klocek
|
r67 | } | ||
Michal Klocek
|
r21 | |||
Michal Klocek
|
r131 | m_path = path; | ||
m_rect = path.boundingRect(); | ||||
Michal Klocek
|
r21 | } | ||
Michal Klocek
|
r144 | void LineChartItem::setPen(const QPen& pen) | ||
Michal Klocek
|
r131 | { | ||
Michal Klocek
|
r139 | m_pen = pen; | ||
} | ||||
Michal Klocek
|
r131 | |||
Michal Klocek
|
r139 | //handlers | ||
Michal Klocek
|
r131 | |||
Michal Klocek
|
r144 | void LineChartItem::handleModelChanged(int index) | ||
Michal Klocek
|
r139 | { | ||
Q_ASSERT(index<m_series->count()); | ||||
if(m_hash.contains(index)){ | ||||
int i = m_hash.value(index); | ||||
QPointF point; | ||||
calculatePoint(point,index,m_series,m_size,m_domain); | ||||
setPoint(i,point); | ||||
Michal Klocek
|
r131 | } | ||
Michal Klocek
|
r139 | update(); | ||
} | ||||
Michal Klocek
|
r131 | |||
Michal Klocek
|
r144 | void LineChartItem::handleDomainChanged(const Domain& domain) | ||
Michal Klocek
|
r139 | { | ||
m_domain = domain; | ||||
updateDomain(); | ||||
Michal Klocek
|
r131 | update(); | ||
} | ||||
Michal Klocek
|
r144 | void LineChartItem::handleGeometryChanged(const QRectF& rect) | ||
Michal Klocek
|
r139 | { | ||
Q_ASSERT(rect.isValid()); | ||||
m_size=rect.size(); | ||||
Michal Klocek
|
r150 | m_clipRect=rect.translated(-rect.topLeft()); | ||
Michal Klocek
|
r139 | updateDomain(); | ||
updateGeometry(); | ||||
setPos(rect.topLeft()); | ||||
update(); | ||||
} | ||||
Michal Klocek
|
r144 | #include "moc_linechartitem_p.cpp" | ||
Michal Klocek
|
r131 | |||
Tero Ahola
|
r30 | QTCOMMERCIALCHART_END_NAMESPACE | ||