1 #include "plot.h"
2 #include "colorbar.h"
3 #include <qevent.h>
4 #if QT_VERSION < 0x040000
5 #include <qwhatsthis.h>
6 #endif
7 #include <qwt_plot_layout.h>
8 #include <qwt_plot_canvas.h>
9 #include <qwt_plot_grid.h>
10 #include <qwt_plot_curve.h>
11 #include <qwt_symbol.h>
12 #include <qwt_scale_widget.h>
13 #include <qwt_wheel.h>
14 #include <stdlib.h>
15 
Plot(QWidget * parent)16 Plot::Plot(QWidget *parent):
17     QwtPlot(parent)
18 {
19     setTitle("Interactive Plot");
20 
21     setCanvasColor(Qt::darkCyan);
22 
23     QwtPlotGrid *grid = new QwtPlotGrid;
24     grid->setMajPen(QPen(Qt::white, 0, Qt::DotLine));
25     grid->attach(this);
26 
27     // axes
28 
29     setAxisScale(QwtPlot::xBottom, 0.0, 100.0);
30     setAxisScale(QwtPlot::yLeft, 0.0, 100.0);
31 
32     // Avoid jumping when label with 3 digits
33     // appear/disappear when scrolling vertically
34 
35     QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
36     sd->setMinimumExtent( sd->extent(QPen(),
37         axisWidget(QwtPlot::yLeft)->font()));
38 
39     plotLayout()->setAlignCanvasToScales(true);
40 
41     insertCurve(Qt::Vertical, Qt::blue, 30.0);
42     insertCurve(Qt::Vertical, Qt::magenta, 70.0);
43     insertCurve(Qt::Horizontal, Qt::yellow, 30.0);
44     insertCurve(Qt::Horizontal, Qt::white, 70.0);
45 
46     replot();
47 
48     // ------------------------------------
49     // We add a color bar to the left axis
50     // ------------------------------------
51 
52     QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(yLeft);
53     scaleWidget->setMargin(10); // area for the color bar
54     d_colorBar = new ColorBar(Qt::Vertical, scaleWidget);
55     d_colorBar->setRange(Qt::red, Qt::darkBlue);
56 #if QT_VERSION >= 0x040000
57     d_colorBar->setFocusPolicy( Qt::TabFocus  );
58 #else
59     d_colorBar->setFocusPolicy( QWidget::TabFocus  );
60 #endif
61 
62     connect(d_colorBar, SIGNAL(selected(const QColor &)),
63         SLOT(setCanvasColor(const QColor &)));
64 
65     // we need the resize events, to lay out the color bar
66     scaleWidget->installEventFilter(this);
67 
68     // ------------------------------------
69     // We add a wheel to the canvas
70     // ------------------------------------
71 
72     d_wheel = new QwtWheel(canvas());
73     d_wheel->setOrientation(Qt::Vertical);
74     d_wheel->setRange(-100, 100);
75     d_wheel->setValue(0.0);
76     d_wheel->setMass(0.2);
77     d_wheel->setTotalAngle(4 * 360.0);
78 
79     connect(d_wheel, SIGNAL(valueChanged(double)),
80         SLOT(scrollLeftAxis(double)));
81 
82     // we need the resize events, to lay out the wheel
83     canvas()->installEventFilter(this);
84 
85 #if QT_VERSION < 0x040000
86     QWhatsThis::add(d_colorBar,
87         "Selecting a color will change the background of the plot.");
88     QWhatsThis::add(scaleWidget,
89         "Selecting a value at the scale will insert a new curve.");
90     QWhatsThis::add(d_wheel,
91         "With the wheel you can move the visible area.");
92     QWhatsThis::add(axisWidget(xBottom),
93         "Selecting a value at the scale will insert a new curve.");
94 #else
95     d_colorBar->setWhatsThis(
96         "Selecting a color will change the background of the plot.");
97     scaleWidget->setWhatsThis(
98         "Selecting a value at the scale will insert a new curve.");
99     d_wheel->setWhatsThis(
100         "With the wheel you can move the visible area.");
101     axisWidget(xBottom)->setWhatsThis(
102         "Selecting a value at the scale will insert a new curve.");
103 #endif
104 
105 }
106 
setCanvasColor(const QColor & c)107 void Plot::setCanvasColor(const QColor &c)
108 {
109     setCanvasBackground(c);
110     replot();
111 }
112 
scrollLeftAxis(double value)113 void Plot::scrollLeftAxis(double value)
114 {
115     setAxisScale(yLeft, value, value + 100.0);
116     replot();
117 }
118 
eventFilter(QObject * object,QEvent * e)119 bool Plot::eventFilter(QObject *object, QEvent *e)
120 {
121     if ( e->type() == QEvent::Resize )
122     {
123         const QSize &size = ((QResizeEvent *)e)->size();
124         if ( object == (QObject *)axisWidget(yLeft) )
125         {
126             const QwtScaleWidget *scaleWidget = axisWidget(yLeft);
127 
128             const int margin = 2;
129 
130             // adjust the color bar to the scale backbone
131             const int x = size.width() - scaleWidget->margin() + margin;
132             const int w = scaleWidget->margin() - 2 * margin;
133             const int y = scaleWidget->startBorderDist();
134             const int h = size.height() -
135                 scaleWidget->startBorderDist() - scaleWidget->endBorderDist();
136 
137             d_colorBar->setGeometry(x, y, w, h);
138         }
139         if ( object == canvas() )
140         {
141             const int w = 16;
142             const int h = 50;
143             const int margin = 2;
144 
145             const QRect cr = canvas()->contentsRect();
146             d_wheel->setGeometry(
147                 cr.right() - margin - w, cr.center().y() - h / 2, w, h);
148         }
149     }
150 
151     return QwtPlot::eventFilter(object, e);
152 }
153 
insertCurve(int axis,double base)154 void Plot::insertCurve(int axis, double base)
155 {
156     Qt::Orientation o;
157     if ( axis == yLeft || axis == yRight )
158         o = Qt::Horizontal;
159     else
160         o = Qt::Vertical;
161 
162     QRgb rgb = (uint)rand();
163     insertCurve(o, QColor(rgb), base);
164     replot();
165 }
166 
insertCurve(Qt::Orientation o,const QColor & c,double base)167 void Plot::insertCurve(Qt::Orientation o,
168     const QColor &c, double base)
169 {
170     QwtPlotCurve *curve = new QwtPlotCurve();
171 
172     curve->setPen(c);
173     curve->setSymbol(QwtSymbol(QwtSymbol::Ellipse,
174         Qt::gray, c, QSize(8, 8)));
175 
176     double x[10];
177     double y[sizeof(x) / sizeof(x[0])];
178 
179     for ( uint i = 0; i < sizeof(x) / sizeof(x[0]); i++ )
180     {
181         double v = 5.0 + i * 10.0;
182         if ( o == Qt::Horizontal )
183         {
184             x[i] = v;
185             y[i] = base;
186         }
187         else
188         {
189             x[i] = base;
190             y[i] = v;
191         }
192     }
193 
194     curve->setData(x, y, sizeof(x) / sizeof(x[0]));
195     curve->attach(this);
196 }
197