Table of Contents
1 renderings
2 Function description
3 key codes
1 Realize the addition, deletion and dynamic update of multiple coordinate systems
2 Coordinate system X-axis synchronization
3 Display cursor in multiple coordinate systems
4 Add curve function
5 Create a single X-axis and multiple Y-axis coordinate system
1 Rendering
2 Function Description
0 Three modes (1) Single X and single Y axis (2) Single X and multiple Y axes (3) Multiple X and multiple Y axes
1. Switching between single coordinate system and multiple coordinate systems is possible.
2 Click the checkbox of QTableWidget to control the number of coordinate systems and display the corresponding curve
3 Display cursor in multiple coordinate systems
4 Change the color of the curve
5 Coordinate system X-axis synchronization
6. Zoom in and out, move left and right, and move up and down the curve
3 key code
Some functions in the header file:
public: int m_WaveIndex; QCPMarginGroup *marginGroup; QString currentFileName; int model; QVector<QCPAxisRect *>axisList; SetYValueDialog mSetYValueDialog; RecFile *pRecGlobal; bool bCursorMoveShow; QVector<QCPItemText *> vectorQCPItemText; QCPAxisRect * rect; void SetModelState(Model _model); void UpdataAll(); void ModelSingleCoord(); void ModelXMulY_Coord(); void ModelMulCoord(); void ModelChange(int _model = 0); void RemoveQCPAxisRectAll(); void SetVisbleQCPAxisRect(); void CreateQCPAxisRect(); void connectAllxAsix(bool on); void CreateQCPAxisRect(int axis_num); void UpdataViewTable(); void ClearViewTable(); void ReloadCustomPlot(); void loadFileTXTFile(QString fileName); void ClearQCPItemText(); void dragEnterEvent(QDragEnterEvent *event) override; //Drag event void dropEvent(QDropEvent *event) override; //Drag and release event };
1 Realize the addition, deletion and dynamic update of multiple coordinate systems
void MainWindow::RemoveQCPAxisRectAll() { ui->customplot->clearGraphs(); for(int i = 0;i < axisList.count();i + + ) { ui->customplot->plotLayout()->remove(axisList.at(i)); QCPAxisRect * rect = axisList.at(i); rect = nullptr; } axisList.clear(); //My personal understanding here is to rearrange the layout after deleting elements. //The number of elements will not change without execution ui->customplot->plotLayout()->simplify(); qDebug()<<ui->customplot->plotLayout()->elementCount(); }
This function deletes all the coordinate axes in QVector
void MainWindow::CreateQCPAxisRect(int axis_num) { ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0)); ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft, marginGroup); for(int i = 0;i < axis_num;i + + ){ QCPAxisRect *rect = new QCPAxisRect(ui->customplot); rect->setMarginGroup(QCP::msLeft, marginGroup); rect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight); rect->axis(QCPAxis::atBottom)->setRange(0,2000); rect->setRangeDrag(Qt::Horizontal | Qt::Vertical); //Horizontal drag rect->setRangeZoom(Qt::Horizontal | Qt::Vertical); //Horizontal scaling if(i == axis_num - 1) { rect->setMargins(QMargins(0, 0, 0, 20)); } if(!ui->customplot->plotLayout()->hasElement(i + 1,0)) ui->customplot->plotLayout()->addElement(i + 1,0,rect); axisList.append(rect); } connectAllxAsix(true); ui->customplot->plotLayout()->simplify(); }
This function creates multiple coordinate systems and adds them to the border group marginGroup to keep the Y axis consistent. Since there is a default coordinate system, here is i + 1
ui->customplot->plotLayout()->addElement(i + 1,0,rect);
2 Coordinate system X-axis synchronization
void MainWindow::connectAllxAsix(bool on) { for (int i = 0; i < axisList.count(); + + i) { if(on){ connect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange ))); connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange ))); } else { disconnect(ui->customplot->axisRect()->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange ))); disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), ui->customplot->axisRect()->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange ))); } for (int j = i + 1; j < axisList.count(); + + j) { if(on) { connect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))) ; connect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))) ; } else { disconnect(axisList.at(i)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(j)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))) ; disconnect(axisList.at(j)->axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axisList.at(i)->axis(QCPAxis::atBottom), SLOT(setRange(QCPRange))) ; } } } }
This function connects signals and slots to achieve synchronization of the X axis
3 Display cursor in multiple coordinate systems
void MainWindow::mouseMoveEvent( QMouseEvent *event ) { //return ; if ( !ui->customplot->viewport().contains( event->pos() ) ) return; if ( RubBand->isVisible() ) { QPoint EndPoint = event->pos(); EndPoint.setY(EndPoint.y() + 58); // EndPoint.setY( ui->customplot->height() ); RubBand->setGeometry( QRect( StartPoint, EndPoint ).normalized() ); } if(!bCursorMoveShow) return ; //Get the mouse coordinates, relative to the coordinates of the parent form int x_pos = event->pos().x(); int y_pos = event->pos().y(); double x_val = 0; //ui->customplot->xAxis->pixelToCoord( x_pos ); double y_val = 0; //ui->customplot->yAxis->pixelToCoord( y_pos ); //Mouse coordinates are converted to CustomPlot internal coordinates for(int i = 0;i < ui->customplot->axisRectCount(); i + + ) { if(event->pos().x() > ui->customplot->axisRects().at(i)->left() & amp; & amp; event->pos().y() < ui ->customplot->axisRects().at(i)->bottom()\ & amp; & amp;event->pos().x() <ui->customplot->axisRects().at(i)->right() & amp; & amp; event->pos().y () > ui->customplot->axisRects().at(i)->top()) { //Don't convert like this // x_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atBottom)->pixelToCoord(x_pos); // y_val = ui->customplot->axisRects().at(i)->axis(QCPAxis::atLeft)->pixelToCoord(y_pos); tracer->setClipAxisRect(ui->customplot->axisRects().at(i)); tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i)); } } x_val = ui->customplot->xAxis->pixelToCoord(x_pos); y_val = ui->customplot->yAxis->pixelToCoord(y_pos); qDebug()<<"x_val:"<<x_val<<",y_val:"<<y_val; QList<QCPGraph*> listQCPGraph = ui->customplot->selectedGraphs(); if(listQCPGraph.isEmpty()) { tracer->setVisible(false); //bSelectGraph = false; tracerLabel->setVisible(false); ui->customplot->replot(); } else { QCPGraph* curGraph = listQCPGraph.at(0); CDatabind* pUserDat = (CDatabind*)curGraph->userData(0); double value; double num = 0; int index = x_val; if(pUserDat) { int m_nWaveInd = pUserDat->m_nWaveInd; num = curGraph->data()->at(index)->key; value = curGraph->data()->at(index)->value; for(int j = mMoveTime[m_nWaveInd].count() -1; j >= 0;j--) { sMoveTime var; var = mMoveTime[m_nWaveInd].at(j); if(var.name == "Y*") { if(var.num != 0) { value = value / var.num; } } else { value = value - var.num; } } } QString mGraphInfo; mGraphInfo = m_pViewTable->currentItem()->text(); tracer->setVisible(true); tracerLabel->setVisible(true); tracer->position->setCoords(x_val, y_val); tracerLabel->setText( mGraphInfo + "\\ ( X:" + QString::number(num) + ",Y:" + QString::number(value) + " )" ); pCurLabel[0]->setText("CurX:" + QString::number(num)); pCurLabel[1]->setText("CurY:" + QString::number(value)); ui->customplot->replot(); } }
The mouseMoveEvent function has been rewritten, where
tracer->setClipAxisRect(ui->customplot->axisRects().at(i)); tracerLabel->setClipAxisRect(ui->customplot->axisRects().at(i));
is the key. The if(pUserDat) fragment is to restore the actual values of operations such as curve zooming, zooming, and translation. You can ignore it.
4 Add curve function
void MainWindow::InsertGraph(RecFile *pRec,int nWaveInd){ QCPGraph *graph; Qt::CheckState bSet; bSet = m_pViewTable->item(nWaveInd,0)->checkState(); if(!bSet & amp; & amp; model == sMulCoord ) graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\ ui->customplot->axisRect()->axis(QCPAxis::atLeft)); else if(model == sMulCoord & amp; & amp; axisList.at(m_WaveIndex) != nullptr){ graph = ui->customplot->addGraph(axisList.at(m_WaveIndex)->axis(QCPAxis::atBottom),axisList.at(m_WaveIndex )->axis(QCPAxis::atLeft)); m_WaveIndex + + ; } else graph = ui->customplot->addGraph(ui->customplot->axisRect()->axis(QCPAxis::atBottom),\ ui->customplot->axisRect()->axis(QCPAxis::atLeft)); graph->setVisible(bSet); graph->setData(pRec->Key,pRec->DatWave[nWaveInd]); graph->setPen(QPen(QColor::fromHsl((nWaveInd * 30) % 256,255 - (nWaveInd * 30) / 16,128))); graph->setName(m_pViewTable->item(nWaveInd,0)->text()); CDatabind *m_pUserData = new CDatabind(); m_pUserData->SetUserData(pRec->nFileInd,nWaveInd); graph->setUserData(0,m_pUserData); graph->setAdaptiveSampling(true); }
The definitions of many variables are not written out and can be flexibly changed as needed.
5 Create a single X-axis and multiple Y-axis coordinate system
void MainWindow::ModelXMulY_Coord() { ui->customplot->plotLayout()->setMargins(QMargins(0, 10, 0, 0)); ui->customplot->plotLayout()->elementAt(0)->setMarginGroup(QCP::msLeft, marginGroup); for(int i = 0;i < m_pViewTable->rowCount();i + + ){ QCPAxis *newAxis = new QCPAxis(ui->customplot->axisRect(),QCPAxis::atLeft); newAxis->setBasePen(QPen(m_pViewTable->item(i,1)->backgroundColor())); newAxis->setTickLabelColor(m_pViewTable->item(i,1)->backgroundColor()); //Add multiple Y axes ui->customplot->axisRect()->addAxis(QCPAxis::atLeft,newAxis); axisList_Y.append(newAxis); } //Depending on whether the CheckBox is visible for(int i = 0;i < m_pViewTable->rowCount() ;i + + ){ if(!m_pViewTable->item(i,0)->checkState()) ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false); } //Whether to display Y-axis coordinates if(!bShowYCoord){ for(int i = 0;i < m_pViewTable->rowCount() ;i + + ){ ui->customplot->axisRect()->axis(QCPAxis::atLeft,i + 1)->setVisible(false); } } qDebug()<<"ModelXMulY_Coord"<<ui->customplot->axisRect()->axes().count(); qDebug()<<"ModelXMulY_Coord QCPAxis::atLeft"<<ui->customplot->axisRect()->axes(QCPAxis::atLeft).count(); ui->customplot->plotLayout()->simplify(); horizontal.clear(); horizontal.append(ui->customplot->axisRect()->axis(QCPAxis::atBottom)); //Set the scaling of the Y-axis coordinate system ui->customplot->axisRect()->setRangeZoomAxes(horizontal,axisList_Y); }