am trying to implement a custom graph going off the QtCharts Callout example. I want to restrict the selection of the chart to a specific area and make it possible to scroll horizontally while still displaying the Axis Values.
the classes i am using are below
here is an example of what i mean
say i want the selection region point1 = (5,0) point2 = (15,8) and the region is a QRect(point1,point2)
All points in the graph should be rendered but I want to be able to scroll sideways and keep the y_axis in view.
One possible solution is to override the mousePressEvent and mouseMoveEvent methods to apply the scroll, and correct using the axes ranges if necessary:
#include <QtWidgets>
#include <QtCharts>
#include <algorithm>
QT_CHARTS_USE_NAMESPACE
class ChartView: public QChartView{
public:
using QChartView::QChartView;
void setRange(qreal xmin, qreal xmax, qreal ymin, qreal ymax){
if(!chart()) return;
if(QValueAxis *xaxis = qobject_cast<QValueAxis *>(chart()->axes(Qt::Horizontal).first())){
xaxis->setRange(xmin, xmax);
}
if(QValueAxis *yaxis = qobject_cast<QValueAxis *>(chart()->axes(Qt::Vertical).first())){
yaxis->setRange(ymin, ymax);
}
}
void setLimits(qreal min, qreal max, Qt::Orientation orientation){
m_limit_min = min;
m_limit_max = max;
m_orientation = orientation;
}
protected:
void mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton && chart())
m_lastMousePos = mapToScene(event->pos());
QGraphicsView::mousePressEvent(event);
}
void mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton && chart()){
QPointF newValue = mapToScene(event->pos());
QPointF delta = newValue - m_lastMousePos;
if(m_orientation == Qt::Horizontal)
chart()->scroll(-delta.x(), 0);
else
chart()->scroll(0, -delta.y());
if(QValueAxis * axis = qobject_cast<QValueAxis *>(chart()->axes(m_orientation).first()) ){
qreal deltaX = axis->max() - axis->min();
if(axis->min() < m_limit_min){
axis->setRange(m_limit_min, m_limit_min + deltaX);
}
else if(axis->max() > m_limit_max){
axis->setRange(m_limit_max - deltaX, m_limit_max);
}
}
m_lastMousePos = newValue;
}
QGraphicsView::mouseMoveEvent(event);
}
private:
QPointF m_lastMousePos;
qreal m_limit_min;
qreal m_limit_max;
Qt::Orientation m_orientation;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ChartView chartView;
chartView.setRenderHint(QPainter::Antialiasing);
chartView.resize(640, 480);
QLineSeries *series = new QLineSeries();
series->append(0, 6);
series->append(2, 4);
series->append(3, 8);
series->append(7, 4);
series->append(10, 5);
*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);
QChart *chart = chartView.chart();
chart->legend()->hide();
chart->addSeries(series);
chart->createDefaultAxes();
chartView.show();
chartView.setRange(5, 15, 0, 8);
chartView.setLimits(0, 20, Qt::Horizontal);
return a.exec();
}