1 #include <QGraphicsScene>
4 #include <QPaintEngine>
5 #include <QPaintDevice>
9 #include "slideritem.h"
10 #include "sliderinfoitem.h"
14 #include "graphitem.h"
16 #include "graphview.h"
21 GraphView::GraphView(QWidget
*parent
)
22 : QGraphicsView(parent
)
24 _scene
= new QGraphicsScene(this);
27 setBackgroundBrush(QBrush(Qt::white
));
28 setViewportUpdateMode(QGraphicsView::FullViewportUpdate
);
29 setRenderHint(QPainter::Antialiasing
, true);
30 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
31 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
33 _xAxis
= new AxisItem(AxisItem::X
);
34 _xAxis
->setZValue(2.0);
35 _yAxis
= new AxisItem(AxisItem::Y
);
36 _yAxis
->setZValue(2.0);
37 _slider
= new SliderItem();
38 _slider
->setZValue(3.0);
39 _sliderInfo
= new SliderInfoItem(_slider
);
40 _sliderInfo
->setZValue(3.0);
41 _info
= new InfoItem();
42 _grid
= new GridItem();
44 connect(_slider
, SIGNAL(positionChanged(const QPointF
&)), this,
45 SLOT(emitSliderPositionChanged(const QPointF
&)));
59 _graphType
= Distance
;
60 _xLabel
= tr("Distance");
63 GraphView::~GraphView()
65 if (_xAxis
->scene() != _scene
)
67 if (_yAxis
->scene() != _scene
)
69 if (_slider
->scene() != _scene
)
71 if (_info
->scene() != _scene
)
73 if (_grid
->scene() != _scene
)
76 for (int i
= 0; i
< _graphs
.count(); i
++)
77 if (_graphs
.at(i
)->scene() != _scene
)
81 void GraphView::createXLabel()
83 _xAxis
->setLabel(QString("%1 [%2]").arg(_xLabel
).arg(_xUnits
));
86 void GraphView::createYLabel()
88 _yAxis
->setLabel(QString("%1 [%2]").arg(_yLabel
).arg(_yUnits
));
91 void GraphView::setYLabel(const QString
&label
)
97 void GraphView::setYUnits(const QString
&units
)
103 void GraphView::setXUnits()
105 if (_graphType
== Distance
) {
106 if (_units
== Metric
) {
107 if (bounds().width() < KMINM
) {
115 if (bounds().width() < MIINM
) {
124 if (bounds().width() < MININS
) {
127 } else if (bounds().width() < HINS
) {
139 void GraphView::setUnits(Units units
)
145 void GraphView::setGraphType(GraphType type
)
150 for (int i
= 0; i
< _graphs
.count(); i
++) {
151 _graphs
.at(i
)->setGraphType(type
);
152 if (_graphs
.at(i
)->scene() == _scene
)
153 _bounds
|= _graphs
.at(i
)->bounds();
156 if (type
== Distance
)
157 _xLabel
= tr("Distance");
159 _xLabel
= tr("Time");
165 void GraphView::showGrid(bool show
)
167 _grid
->setVisible(show
);
170 void GraphView::loadGraph(const Graph
&graph
, PathItem
*path
, int id
)
172 if (graph
.size() < 2)
175 GraphItem
*gi
= new GraphItem(graph
);
176 gi
->setGraphType(_graphType
);
178 gi
->setColor(_palette
.nextColor());
179 gi
->setWidth(_width
);
181 connect(this, SIGNAL(sliderPositionChanged(qreal
)), gi
,
182 SLOT(emitSliderPositionChanged(qreal
)));
183 connect(gi
, SIGNAL(sliderPositionChanged(qreal
)), path
,
184 SLOT(moveMarker(qreal
)));
185 connect(path
, SIGNAL(selected(bool)), gi
, SLOT(selected(bool)));
189 if (!_hide
.contains(id
)) {
192 _bounds
|= gi
->bounds();
197 void GraphView::removeItem(QGraphicsItem
*item
)
199 if (item
->scene() == _scene
)
200 _scene
->removeItem(item
);
203 void GraphView::addItem(QGraphicsItem
*item
)
205 if (item
->scene() != _scene
)
206 _scene
->addItem(item
);
209 void GraphView::showGraph(bool show
, int id
)
218 for (int i
= 0; i
< _graphs
.count(); i
++) {
219 GraphItem
* gi
= _graphs
.at(i
);
220 if (_hide
.contains(gi
->id()))
225 _bounds
|= gi
->bounds();
230 void GraphView::redraw()
232 redraw(viewport()->size() - QSizeF(MARGIN
, MARGIN
));
235 QRectF
GraphView::bounds() const
238 br
.moveTopLeft(QPointF(br
.left(), -br
.top() - br
.height()));
242 void GraphView::redraw(const QSizeF
&size
)
250 if (_visible
.isEmpty() || _bounds
.isNull()) {
256 _scene
->setSceneRect(QRectF());
266 rx
= RangeF(bounds().left() * _xScale
, bounds().right() * _xScale
);
267 ry
= RangeF(bounds().top() * _yScale
+ _yOffset
, bounds().bottom() * _yScale
269 if (ry
.size() < _minYRange
)
270 ry
.resize(_minYRange
);
272 _xAxis
->setRange(rx
);
273 _yAxis
->setRange(ry
);
274 mx
= _xAxis
->margin();
275 my
= _yAxis
->margin();
278 if (r
.height() < _minYRange
)
279 r
.adjust(0, -(_minYRange
/2 - r
.height()/2), 0,
280 _minYRange
/2 - r
.height()/2);
282 sx
= (size
.width() - (my
.width() + mx
.width())) / r
.width();
283 sy
= (size
.height() - (mx
.height() + my
.height())
284 - _info
->boundingRect().height()) / r
.height();
286 for (int i
= 0; i
< _visible
.size(); i
++)
287 _visible
.at(i
)->setScale(sx
, sy
);
289 QPointF
p(r
.left() * sx
, r
.top() * sy
);
290 QSizeF
s(r
.width() * sx
, r
.height() * sy
);
292 if (r
.height() < _minYRange
* sy
)
293 r
.adjust(0, -(_minYRange
/2 * sy
- r
.height()/2), 0,
294 (_minYRange
/2) * sy
- r
.height()/2);
296 _xAxis
->setSize(r
.width());
297 _yAxis
->setSize(r
.height());
298 _xAxis
->setPos(r
.bottomLeft());
299 _yAxis
->setPos(r
.bottomLeft());
301 _grid
->setSize(r
.size());
302 _grid
->setTicks(_xAxis
->ticks(), _yAxis
->ticks());
303 _grid
->setPos(r
.bottomLeft());
306 updateSliderPosition();
308 r
|= _xAxis
->sceneBoundingRect();
309 r
|= _yAxis
->sceneBoundingRect();
310 _info
->setPos(r
.topLeft() + QPointF(r
.width()/2
311 - _info
->boundingRect().width()/2, -_info
->boundingRect().height()));
313 _scene
->setSceneRect(_scene
->itemsBoundingRect());
316 void GraphView::resizeEvent(QResizeEvent
*)
321 void GraphView::mousePressEvent(QMouseEvent
*e
)
323 if (e
->button() == Qt::LeftButton
)
324 newSliderPosition(mapToScene(e
->pos()));
326 QGraphicsView::mousePressEvent(e
);
329 void GraphView::plot(QPainter
*painter
, const QRectF
&target
)
331 qreal ratio
= painter
->paintEngine()->paintDevice()->logicalDpiX()
333 QSizeF canvas
= QSizeF(target
.width() / ratio
, target
.height() / ratio
);
335 setUpdatesEnabled(false);
337 if (_slider
->pos().x() == _slider
->area().left())
339 _scene
->render(painter
, target
);
342 setUpdatesEnabled(true);
345 void GraphView::clear()
350 for (int i
= 0; i
< _graphs
.count(); i
++)
360 _scene
->setSceneRect(0, 0, 0, 0);
363 void GraphView::updateSliderPosition()
365 if (bounds().width() <= 0)
368 if (_sliderPos
<= bounds().right() && _sliderPos
>= bounds().left()) {
369 _slider
->setPos((_sliderPos
/ bounds().width())
370 * _slider
->area().width(), _slider
->area().bottom());
371 _slider
->setVisible(!_visible
.isEmpty());
373 _slider
->setPos(_slider
->area().left(), _slider
->area().bottom());
374 _slider
->setVisible(false);
380 void GraphView::updateSliderInfo()
382 _sliderInfo
->setVisible(_visible
.count() == 1);
383 if (!_sliderInfo
->isVisible())
386 QRectF
br(_visible
.first()->bounds());
387 if (br
.height() < _minYRange
)
388 br
.adjust(0, -(_minYRange
/2 - br
.height()/2), 0,
389 _minYRange
/2 - br
.height()/2);
391 qreal y
= _visible
.first()->yAtX(_sliderPos
);
392 qreal r
= (y
- br
.bottom()) / br
.height();
394 qreal pos
= (_sliderPos
/ bounds().width()) * _slider
->area().width();
395 SliderInfoItem::Side s
= (pos
+ _sliderInfo
->boundingRect().width()
396 > _slider
->area().right()) ? SliderInfoItem::Left
: SliderInfoItem::Right
;
398 _sliderInfo
->setSide(s
);
399 _sliderInfo
->setPos(QPointF(0, _slider
->boundingRect().height() * r
));
400 _sliderInfo
->setText(QString::number(-y
* _yScale
+ _yOffset
, 'f',
404 void GraphView::emitSliderPositionChanged(const QPointF
&pos
)
406 if (_slider
->area().width() <= 0)
409 _sliderPos
= (pos
.x() / _slider
->area().width()) * bounds().width();
410 _sliderPos
= qMax(_sliderPos
, bounds().left());
411 _sliderPos
= qMin(_sliderPos
, bounds().right());
412 updateSliderPosition();
414 emit
sliderPositionChanged(_sliderPos
);
417 void GraphView::setSliderPosition(qreal pos
)
419 if (_visible
.isEmpty())
423 updateSliderPosition();
426 void GraphView::newSliderPosition(const QPointF
&pos
)
428 if (_slider
->area().contains(pos
))
429 _slider
->setPos(pos
);
432 void GraphView::addInfo(const QString
&key
, const QString
&value
)
434 _info
->insert(key
, value
);
437 void GraphView::clearInfo()
442 void GraphView::setPalette(const Palette
&palette
)
447 for (int i
= 0; i
< _graphs
.count(); i
++)
448 _graphs
.at(i
)->setColor(_palette
.nextColor());
451 void GraphView::setGraphWidth(int width
)
455 for (int i
= 0; i
< _graphs
.count(); i
++)
456 _graphs
.at(i
)->setWidth(width
);
459 void GraphView::useOpenGL(bool use
)
462 setViewport(new OPENGL_WIDGET
);
464 setViewport(new QWidget
);