~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/gui/dataplotwidget/plotdisplay.cpp

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2020 by santiago González                               *
 
3
 *   santigoro@gmail.com                                                   *
 
4
 *                                                                         *
 
5
 *   This program is free software; you can redistribute it and/or modify  *
 
6
 *   it under the terms of the GNU General Public License as published by  *
 
7
 *   the Free Software Foundation; either version 3 of the License, or     *
 
8
 *   (at your option) any later version.                                   *
 
9
 *                                                                         *
 
10
 *   This program is distributed in the hope that it will be useful,       *
 
11
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
12
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
13
 *   GNU General Public License for more details.                          *
 
14
 *                                                                         *
 
15
 *   You should have received a copy of the GNU General Public License     *
 
16
 *   along with this program; if not, see <http://www.gnu.org/licenses/>.  *
 
17
 *                                                                         *
 
18
 ***************************************************************************/
 
19
 
 
20
 
 
21
#include <QBrush>
 
22
#include <QPen>
 
23
 
 
24
#include "plotdisplay.h"
 
25
#include "mainwindow.h"
 
26
#include "circuitview.h"
 
27
#include "simulator.h"
 
28
 
 
29
PlotDisplay::PlotDisplay( QWidget* parent )
 
30
           : QWidget( parent )
 
31
{
 
32
    for( int i=0; i<2; i++ )
 
33
    {
 
34
        m_scaleY[i] = 1;
 
35
        m_hPos[i] = 0;
 
36
        m_vMax[i] = 0;
 
37
        m_vMin[i] = 0;
 
38
        m_data[i] = 0l;
 
39
        m_foregroundA[i] = QPixmap( 100, 100 );
 
40
        m_foregroundB[i] = QPixmap( 100, 100 );
 
41
        m_foreground[i]  = &m_foregroundA[i];
 
42
    }
 
43
    m_margin = 8;
 
44
    m_background = QPixmap( 100, 100 );
 
45
 
 
46
    double fontScale = MainWindow::self()->fontScale();
 
47
    m_fontB.setPixelSize(int(8*fontScale));
 
48
    m_fontB.setBold(true);
 
49
    m_fontS.setPixelSize(int(7*fontScale));
 
50
 
 
51
    m_scaleColor[0] = QColor( 90, 90, 90 );
 
52
    m_scaleColor[1] = QColor( 130, 130, 130 );
 
53
    m_scaleColor[2] = QColor( 230, 230, 230 );
 
54
    m_color[0] = QColor( 240, 240, 100 ); //QColor( 190, 190, 0 );
 
55
    m_color[1] = QColor( 220, 220, 255 ); //QColor( 255, 110, 50 );
 
56
    m_color[2] = QColor( 255, 255, 255 );
 
57
 
 
58
    setMouseTracking(true);
 
59
}
 
60
 
 
61
QSize PlotDisplay::minimumSizeHint() const  {  return QSize( m_width, m_height );  }
 
62
 
 
63
QSize PlotDisplay::sizeHint() const  { return QSize( m_width, m_height ); }
 
64
 
 
65
void PlotDisplay::setSize( int width, int height )
 
66
{
 
67
    m_width  = width+6*m_margin;
 
68
    m_height = height+2*m_margin;
 
69
 
 
70
    m_sizeX = width;
 
71
    m_sizeY = height;
 
72
    m_scaleX = 1;
 
73
 
 
74
    setFixedSize( m_width, m_height );
 
75
    m_background = m_background.scaled( m_width, m_height );
 
76
 
 
77
    for( int i=0; i<2; i++ )
 
78
    {
 
79
        m_foregroundA[i] = m_foregroundA[i].scaled( m_sizeX+2, m_sizeY+2 );
 
80
        m_foregroundB[i] = m_foregroundB[i].scaled( m_sizeX+2, m_sizeY+2 );
 
81
        m_vTick[i] = 1;
 
82
        m_vPos[i] = 0;
 
83
        m_data[i] = 0l;
 
84
    }
 
85
    updateValues();
 
86
 
 
87
    QPainter p( &m_background );
 
88
    drawBackground( &p );
 
89
    p.end();
 
90
}
 
91
 
 
92
void PlotDisplay::setMaxMin( int ch, double max, double min )
 
93
{
 
94
    m_vMax[ch]  = max;
 
95
    m_vMin[ch]  = min;
 
96
 
 
97
    double ampli = max-min;
 
98
    m_ampli[ch] = ampli;
 
99
    m_scaleY[ch] = ampli/(m_vTick[ch]*10);
 
100
    updateValues();
 
101
}
 
102
 
 
103
void PlotDisplay::setData( int ch, QList<QPointF>* data )
 
104
{
 
105
    m_data[ch] = data;
 
106
    updateValues();
 
107
}
 
108
 
 
109
void PlotDisplay::setXFrame( uint64_t tf )
 
110
{
 
111
    m_scaleX = (double)m_sizeX/(double)tf;
 
112
    updateValues();
 
113
}
 
114
 
 
115
void PlotDisplay::setVTick( int ch, double tick )
 
116
{
 
117
    m_vTick[ch] = tick;
 
118
    m_scaleY[ch] = m_ampli[ch]/(tick*10);
 
119
    updateValues();
 
120
}
 
121
 
 
122
void PlotDisplay::setVPos( int ch, double vPos )
 
123
{
 
124
    m_vPos[ch] = -vPos;
 
125
    updateValues();
 
126
}
 
127
 
 
128
void PlotDisplay::setHPos( int ch, int64_t hPos )
 
129
{
 
130
    m_hPos[ch] = -hPos;
 
131
    update();
 
132
}
 
133
 
 
134
void PlotDisplay::updateValues()
 
135
{
 
136
    m_hCenter = (double)m_width/2;
 
137
    m_vCenter = (double)m_height/2;
 
138
    m_ceroX = m_margin*3;
 
139
    m_endX  = m_width-m_ceroX;
 
140
    m_ceroY = m_margin;
 
141
    m_endS  = m_height-m_margin;
 
142
    m_lineX = m_ceroX;
 
143
    m_linWi = (4+6*m_sizeY/200)/10;
 
144
 
 
145
    for( int i=0; i<2; i++ )
 
146
    {
 
147
        m_endY[i] = m_vCenter+(m_height-m_margin*2)*m_scaleY[i]/2;
 
148
        m_midV[i] = (m_vMax[i]+m_vMin[i])/2;
 
149
        m_sclY[i] = m_sizeY/(m_vTick[i]*10);
 
150
        m_posY[i] = m_vMin[i]+m_vPos[i];
 
151
        m_vMaxPos[i] = m_endY[i]-(m_vMax[i]-m_posY[i])*m_sclY[i];
 
152
        m_vMinPos[i] = m_endY[i]-(m_vMin[i]-m_posY[i])*m_sclY[i];
 
153
    }
 
154
    update();
 
155
}
 
156
 
 
157
void PlotDisplay::drawBackground( QPainter* p )
 
158
{
 
159
    //p->setRenderHint( QPainter::Antialiasing, true );
 
160
 
 
161
    p->setBrush( QColor( 0, 0, 0 ) );
 
162
    p->drawRoundRect(0, 0, m_width, m_height, 7, 7 );
 
163
 
 
164
    QPen pen( m_scaleColor[0], 1.5*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
165
    p->setPen( pen );
 
166
    for( double i=m_ceroY; i<=m_endS; i+=m_sizeY/10. )
 
167
        p->drawLine( QPointF(m_ceroX, i), QPointF(m_endX, i) ); //Horizontal lines
 
168
 
 
169
    for( double i=m_lineX; i<=m_endX; i+=m_sizeX/10. )
 
170
        p->drawLine( QPointF(i, m_ceroY), QPointF(i, m_endS) ); //Vertical lines
 
171
 
 
172
    QPen pen2( m_scaleColor[1], 1*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
173
    p->setPen( pen2 );
 
174
 
 
175
    double m = 2*m_linWi;
 
176
    for( double i=m_ceroY; i<=m_endS; i+=m_sizeY/50. )
 
177
        p->drawLine( QPointF(m_hCenter-m, i), QPointF(m_hCenter+m, i) ); //Horizontal Marks
 
178
 
 
179
    for( double i=m_lineX; i<=m_endX; i+=m_sizeX/50. )
 
180
        p->drawLine( QPointF(i, m_vCenter-m), QPointF(i, m_vCenter+m) ); //Vertical Marks
 
181
 
 
182
    QPen pen3( m_scaleColor[1], 1.5*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
183
    p->setPen( pen3 );
 
184
    p->drawLine( m_ceroX, m_vCenter, m_endX, m_vCenter );  //Horizontal Center line
 
185
    p->drawLine( m_hCenter, m_ceroY, m_hCenter, m_endS );  //Vertical Center line
 
186
}
 
187
 
 
188
/*void PlotDisplay::clear( int ch )
 
189
{
 
190
    //for( int i=0; i<2; i++ )
 
191
        m_foregroundA[ch].fill( Qt::transparent );
 
192
        m_foregroundB[ch].fill( Qt::transparent );
 
193
}*/
 
194
 
 
195
void PlotDisplay::paintEvent( QPaintEvent* /* event */ )
 
196
{
 
197
    QPainter p( this );
 
198
 
 
199
    drawBackground( &p );
 
200
    p.setRenderHint( QPainter::Antialiasing, true );
 
201
 
 
202
    QPointF P1;
 
203
    double x1;
 
204
    double y1;
 
205
    double x2;
 
206
    double y2;
 
207
 
 
208
    for( int i=0; i<2; i++ )
 
209
    {
 
210
      if( m_data[i] )
 
211
        {
 
212
            QPen pen1( m_color[i], 0.5*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
213
            p.setPen( pen1 );
 
214
 
 
215
            p.drawLine( m_ceroX, m_vMaxPos[i], m_endX, m_vMaxPos[i] );   //Horizontal Max V line
 
216
            p.drawLine( m_ceroX, m_vMinPos[i], m_endX, m_vMinPos[i] );   //Horizontal Min V line
 
217
 
 
218
            // PRINT DATA
 
219
            QPen pen2( m_color[i], 2*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
220
            p.setPen( pen2 );
 
221
 
 
222
            int k = 0;
 
223
            double filter = m_filter*m_sclY[i];//m_ampli[i]*m_sclY[i]/4; //
 
224
 
 
225
            for( QPointF P2 : *m_data[i] )
 
226
            {
 
227
                x2 = P2.x()*m_scaleX+m_margin*3+m_hPos[i]*m_scaleX;
 
228
                y2 = m_endY[i]-(P2.y()-m_posY[i])*m_sclY[i];
 
229
                P2.setX( x2 );
 
230
                P2.setY( y2 );
 
231
 
 
232
                if( k == 0 ) // First Point
 
233
                {
 
234
                    if( x2 > 0 ) P1 = QPointF( 0, y2 ); // We need another point before
 
235
                    else         P1 = P2;
 
236
                    k++;
 
237
                    continue;
 
238
                }
 
239
                x1 = P1.x();
 
240
                y1 = P1.y();
 
241
 
 
242
                if(( x1<0 && x2<0 ) ||( x1>m_width && x2>m_width )) // Out of display
 
243
                {
 
244
                    P1 = P2; continue;
 
245
                }
 
246
                if( fabs( y2-y1 ) <= filter ) p.drawLine( P1, P2 );
 
247
                else
 
248
                {
 
249
                    QPointF PM = QPointF( x2, y1 );
 
250
                    p.drawLine( P1, PM );
 
251
                    p.drawLine( PM, P2 );
 
252
                }
 
253
                P1 = P2;
 
254
            }
 
255
 
 
256
            // Draw Rects to crop data plots
 
257
            p.fillRect( 0, 0, m_margin*3, m_height, QColor( 10, 15, 50 ) );
 
258
            p.fillRect( m_sizeX+m_margin*3, 0, m_margin*3, m_height, QColor( 10, 15, 50 ) );
 
259
        }
 
260
    }
 
261
    for( int i=0; i<2; i++ ) // Draw scales, text, Max-Min
 
262
    {
 
263
        if( m_data[i] )
 
264
        {
 
265
            int xPos = 2+i*(m_sizeX+3*m_margin);
 
266
 
 
267
            QPen pen3( m_color[i], 1.5*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
268
            p.setPen( pen3 );
 
269
            p.setFont( m_fontS );
 
270
 
 
271
            // Draw Background scale values
 
272
            int s = 0;
 
273
            for( double j=m_ceroY; j<=m_endS; j+=m_sizeY/10 )
 
274
            {
 
275
                //p.drawLine( m_ceroX, i, m_endX, i ); //Horizontal lines
 
276
 
 
277
                int decs = 0;
 
278
                double volTick = (m_vTick[i]*5-m_vTick[i]*s++);
 
279
                //int vt = volTick;
 
280
                //volTick = ((double)vt+0.5)/100;
 
281
                if     ( volTick < 10)   decs = 2;
 
282
                else if( volTick < 100)  decs = 1;
 
283
 
 
284
                p.drawText( xPos, j-5, m_width, 10, Qt::AlignVCenter, QString::number( volTick,'f', decs) );
 
285
            }
 
286
 
 
287
            /*p.drawText( xPos,           3, m_width, 10,       Qt::AlignVCenter, QString::number( m_midV[i]+m_vTick[i]*5,'f', 2) );
 
288
            p.drawText( xPos, m_vCenter-5, m_width, m_margin, Qt::AlignVCenter, QString::number( m_midV[i]          ,'f', 2) );
 
289
            p.drawText( xPos,    m_endS-5, m_width, 10,       Qt::AlignVCenter, QString::number( m_midV[i]-m_vTick[i]*5,'f', 2) );
 
290
*/
 
291
            // Draw Rects behind Max & Min Numbers
 
292
            p.fillRect( xPos, m_vMaxPos[i]-4, 21, 8, QColor( 10, 15, 50 ) );
 
293
            p.fillRect( xPos, m_vMinPos[i]-4, 21, 8, QColor( 10, 15, 50 ) );
 
294
 
 
295
            // Draw Max & Min Values
 
296
            p.setFont( m_fontB );
 
297
            //p.setPen( m_color[i] );
 
298
            p.drawText( xPos, m_vMaxPos[i]-5, m_width, 10, Qt::AlignVCenter, QString::number(m_vMax[i],'f', 2) );
 
299
            p.drawText( xPos, m_vMinPos[i]-5, m_width, 10, Qt::AlignVCenter, QString::number(m_vMin[i],'f', 2) );
 
300
        }
 
301
    }
 
302
    QPoint cPos = QCursor::pos()-mapToGlobal( QPoint(0, 0) );
 
303
    qreal scale = CircuitView::self()->getScale();
 
304
    int cursorX = cPos.x()/scale;
 
305
    int cursorY = cPos.y()/scale;
 
306
 
 
307
    if( (cursorX > m_ceroX) && (cursorX < m_endX ) // Draw Cursor
 
308
     && (cursorY > 0) && (cursorY < m_height) )
 
309
    {
 
310
        QPen pen1( m_scaleColor[2], 1*m_linWi, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin );
 
311
        p.setPen( pen1 );
 
312
 
 
313
        p.drawLine( cursorX, 0, cursorX, m_height );  //Horizontal Cursor V line
 
314
        p.drawLine( m_ceroX, cursorY, m_endX, cursorY );   //Horizontal Cursor H line m_scaleX[i]
 
315
 
 
316
        pen1.setColor( Qt::white );
 
317
        p.setPen( pen1 );
 
318
        double volt = (double)(cursorX-m_hCenter)/m_scaleX/1e6;
 
319
        p.drawText( cursorX-25, cursorY-10, 50, 10, Qt::AlignLeft, QString::number( volt,'f', 1)+" us" );
 
320
    }
 
321
    p.end();
 
322
}
 
323
 
 
324
 
 
325
#include "moc_plotdisplay.cpp"