#include "ChannelChartForm.h" #include "ui_ChannelChartForm.h" ChannelChartForm::ChannelChartForm(QWidget *parent) : QWidget(parent), ui(new Ui::ChannelChartForm) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭后释放本对象 this->setWindowFlags(Qt::FramelessWindowHint); resize(SettingConfig::getInstance().WINDOW_WIDTH, SettingConfig::getInstance().WINDOW_HEIGHT); } ChannelChartForm::~ChannelChartForm() { delete ui; } void ChannelChartForm::setTitleText(QString titleText) { ui->labChartTitle->setText(titleText); } void ChannelChartForm::initDataChart(QList<QStringList> hisDataVect) { QPen pen; pen.setColor(QColor("#2ed573")); // 曲线颜色(绿色) pen.setWidth(1); //曲线线宽 QCPGraph * graph = ui->dataPlot->addGraph(); graph->setName("钟差(ns)"); graph->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) graph->setPen(pen); QCPGraph * graphResi = ui->analysisPlot->addGraph(); graphResi->setName("钟差(ns)"); graphResi->setAdaptiveSampling(true); // 默认启用自适应采样(绘图) graphResi->setPen(pen); // 时间坐标轴 seconds since Epoch (January 1, 1970, 00:00 UTC). QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime); timeTicker->setDateTimeFormat("MM-dd hh:mm:ss"); // 横轴刻度单位:分钟 ui->dataPlot->xAxis->setTicker(timeTicker); ui->dataPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× ui->dataPlot->yAxis->setNumberPrecision(12); // Y 轴:精度,有效数字的位数 ui->analysisPlot->xAxis->setTicker(timeTicker); ui->analysisPlot->yAxis->setNumberFormat("gbc"); // Y 轴:g灵活的格式,b漂亮的指数形式,c乘号改成× ui->analysisPlot->yAxis->setNumberPrecision(12); // Y 轴:精度,有效数字的位数 ui->dataPlot->setBackground(QColor("#0B1425")); ui->analysisPlot->setBackground(QColor("#0B1425")); // 背景色 ui->dataPlot->xAxis->setBasePen(QPen(Qt::white)); ui->dataPlot->xAxis->setTickPen(QPen(Qt::white)); ui->dataPlot->xAxis->setPadding(5); ui->dataPlot->xAxis->grid()->setVisible(true); ui->dataPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); ui->dataPlot->xAxis->setTickLabelColor(Qt::white); ui->dataPlot->xAxis->setLabelColor(Qt::white); ui->dataPlot->xAxis->setLabel("时间"); ui->analysisPlot->xAxis->setBasePen(QPen(Qt::white)); ui->analysisPlot->xAxis->setTickPen(QPen(Qt::white)); ui->analysisPlot->xAxis->setPadding(5); ui->analysisPlot->xAxis->grid()->setVisible(true); ui->analysisPlot->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); ui->analysisPlot->xAxis->setTickLabelColor(Qt::white); ui->analysisPlot->xAxis->setLabelColor(Qt::white); ui->analysisPlot->xAxis->setLabel("时间"); ui->dataPlot->yAxis->setPadding(5); // a bit more space to the left border ui->dataPlot->yAxis->setLabel("钟差(ns)"); ui->dataPlot->yAxis->setBasePen(QPen(Qt::white)); ui->dataPlot->yAxis->setTickPen(QPen(Qt::white)); //ui->dataPlot->yAxis->setSubTickPen(QPen(Qt::white)); //ui->dataPlot->yAxis->grid()->setSubGridVisible(true); ui->dataPlot->yAxis->setTickLabelColor(Qt::white); ui->dataPlot->yAxis->setLabelColor(Qt::white); ui->dataPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); //ui->dataPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); ui->analysisPlot->yAxis->setPadding(5); // a bit more space to the left border ui->analysisPlot->yAxis->setLabel("钟差(ns)"); ui->analysisPlot->yAxis->setBasePen(QPen(Qt::white)); ui->analysisPlot->yAxis->setTickPen(QPen(Qt::white)); //ui->analysisPlot->yAxis->setSubTickPen(QPen(Qt::white)); //ui->analysisPlot->yAxis->grid()->setSubGridVisible(true); ui->analysisPlot->yAxis->setTickLabelColor(Qt::white); ui->analysisPlot->yAxis->setLabelColor(Qt::white); ui->analysisPlot->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine)); //ui->analysisPlot->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine)); double minTm = hisDataVect.first().at(0).toLongLong() / 1000; double maxTm = hisDataVect.last().at(0).toLongLong() / 1000; double minValue = hisDataVect.first().at(1).toDouble() * 1E9; double maxValue = hisDataVect.last().at(1).toDouble() * 1E9; QVector<QCPGraphData> vecPoints; double minResidual = 0.0; double maxResidual = 0.0; QVector<QCPGraphData> resiPoints; QPen tpen; tpen.setColor(QColor("#F1C40F")); // 曲线颜色(yellow) tpen.setWidth(2); // 线宽 tpen.setStyle(Qt::DashDotLine); tracer = new QCPItemTracer(ui->dataPlot); //生成游标 tracer->setStyle(QCPItemTracer::tsCrosshair); tracer->setPen(tpen); tracerResi = new QCPItemTracer(ui->analysisPlot); //生成游标 tracerResi->setStyle(QCPItemTracer::tsCrosshair); tracerResi->setPen(tpen); connect(ui->dataPlot, &QCustomPlot::mouseMove, this, &ChannelChartForm::mouseMoveEvent); connect(ui->analysisPlot, &QCustomPlot::mouseMove, this, &ChannelChartForm::showTracerResidual); double timeVec[hisDataVect.size()]; double valueVec[hisDataVect.size()]; for (int i = 0; i < hisDataVect.size(); i++) { // 新的数据点 QCPGraphData onePoint; QDateTime dtime = QDateTime::fromSecsSinceEpoch(hisDataVect.at(i).at(0).toLongLong() / 1000); // 日期时间 onePoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); onePoint.value = hisDataVect.at(i).at(1).toDouble() * 1E9; timeVec[i] = onePoint.key; valueVec[i] = onePoint.value; vecPoints.append(onePoint); if (hisDataVect.at(i).at(1).toDouble() * 1E9 < minValue) { minValue = hisDataVect[i].at(1).toDouble() * 1E9; } if (hisDataVect.at(i).at(1).toDouble() * 1E9 > maxValue) { maxValue = hisDataVect[i].at(1).toDouble() * 1E9; } } graph->data()->clear(); graph->data()->set(vecPoints, true); ui->dataPlot->xAxis->setRange(minTm, maxTm); ui->dataPlot->yAxis->setRange(minValue, maxValue); ui->dataPlot->legend->setVisible(false); ui->dataPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); // 设置曲线可以拖动 可以缩放 // 计算残差部分 LinearRegression lineReg; lineReg.xArray = timeVec; lineReg.yArray = valueVec; lineReg.calcLineRegParams(hisDataVect.size()); for (int i = 0; i < hisDataVect.size(); i++) { // 新的残差数据点 QCPGraphData resiPoint; QDateTime dtime = QDateTime::fromSecsSinceEpoch(hisDataVect.at(i).at(0).toLongLong() / 1000); // 日期时间 resiPoint.key = QCPAxisTickerDateTime::dateTimeToKey(dtime); resiPoint.value = hisDataVect.at(i).at(1).toDouble() * 1E9 - (lineReg.slope * resiPoint.key + lineReg.intercept); resiPoints.append(resiPoint); if (resiPoint.value < minResidual) { minResidual = resiPoint.value; } if (resiPoint.value > maxResidual) { maxResidual = resiPoint.value; } } graphResi->data()->clear(); graphResi->data()->set(resiPoints, true); ui->analysisPlot->xAxis->setRange(minTm, maxTm); ui->analysisPlot->yAxis->setRange(minResidual, maxResidual); ui->analysisPlot->legend->setVisible(false); ui->analysisPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); // 设置曲线可以拖动 可以缩放 } void ChannelChartForm::on_btnChartClose_clicked() { this->close(); } void ChannelChartForm::mouseMoveEvent(QMouseEvent *event) { //将像素点转换成qcustomplot中的坐标值,并通过setGraphKey将锚点值设为真实数据值。tracer->setGraphKey(xAxis->pixelToCoord(event->pos().x())); //获得鼠标位置处对应的横坐标数据x qulonglong x = ui->dataPlot->xAxis->pixelToCoord(event->pos().x()); this->drawPlotTracer(x); } void ChannelChartForm::showTracerResidual(QMouseEvent *event) { //获得鼠标位置处对应的横坐标数据x qulonglong x = ui->analysisPlot->xAxis->pixelToCoord(event->pos().x()); this->drawPlotTracer(x); } void ChannelChartForm::drawPlotTracer(qulonglong x) { QCPGraph *mGraph = ui->dataPlot->graph(0); QCPGraph *mGraphResi = ui->analysisPlot->graph(0); QString time = QDateTime::fromSecsSinceEpoch(x).toString("yyyy-MM-dd HH:mm:ss"); //将像素点转换成qcustomplot中的坐标值,并通过setGraphKey将锚点值设为真实数据值。tracer->setGraphKey(xAxis->pixelToCoord(event->pos().x())); //显示锚点 tracer->setVisible(true); tracer->setGraph(mGraph);//将锚点设置到被选中的曲线上 tracer->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x tracer->setInterpolating(false); //游标的纵坐标可以通过曲线数据线性插值自动获得 tracer->updatePosition(); //使得刚设置游标的横纵坐标位置生效 //显示锚点 tracerResi->setVisible(true); tracerResi->setGraph(mGraphResi);//将锚点设置到被选中的曲线上 tracerResi->setGraphKey(x); //将游标横坐标设置成刚获得的横坐标数据x tracerResi->setInterpolating(false); //游标的纵坐标可以通过曲线数据线性插值自动获得 tracerResi->updatePosition(); //使得刚设置游标的横纵坐标位置生效 double yValue = tracer->position->value(); double yValueResi = tracerResi->position->value(); QPoint pos((SettingConfig::getInstance().WINDOW_WIDTH - 500) / 2, -15); QString toolLabel = "时间:%1\r\n钟差(ns):%2\t残差(ns):%3"; //显示tip框 QToolTip::showText(pos, toolLabel.arg(time).arg(QString::number(yValue, 'f', 3)).arg(QString::number(yValueResi, 'f', 6)), this, this->rect(), 5*1000); //重绘 ui->dataPlot->replot(); ui->analysisPlot->replot(); }