#include "TransparentDraggableCorePhysics.h" #include "PropertyWidget.h" extern double g_dPixelPerCm;//每厘米像素数 //static GeoIndicatorGenerator m_drawGeo; TransparentDraggableCorePhysics::TransparentDraggableCorePhysics(QMyCustomPlot *parentPlot, QString strUuid, double minWidth, QString strTitle) : QObject(parentPlot), mPlot(parentPlot), mstrTitle(strTitle), mMinWidth(minWidth) { m_strUuid = strUuid; // initRect(); } TransparentDraggableCorePhysics::~TransparentDraggableCorePhysics() { if(mPlot) { } } //设置最小宽度 void TransparentDraggableCorePhysics::setMinWidth(double minWidth) { mMinWidth = minWidth; } //设置标题 void TransparentDraggableCorePhysics::setTitle(QString strTitle) { mstrTitle = strTitle; //mPlot->replot(); } // 设置矩形范围 void TransparentDraggableCorePhysics::setRange(double left_Low, double right_Hight, double lY2, bool bReplot) { m_left_Low = left_Low; m_right_Hight = right_Hight; double lY1 = mPlot->yAxis->range().lower;//+10 // double lY2 = mPlot->yAxis->range().upper; for(int i =0; im_x.size(); i++) { if(abs(mPlot->m_x[i]-left_Low) < 0.1) { lY1 = mPlot->m_y[i]; break; } } m_lY1 = lY1; // lY2除以实际左到右刻度数值 // lY2 = lY2 / (getCpRightScale() - getCpLeftScale()) * 100; double minV = getCpLeftScale(); double maxV = getCpRightScale(); double value = lY2; double finalValue = 0; int scaleType = getCpScaleType(); // 0=线性 1=对数 2=倾角 if (scaleType == 0) { // 线性(原来的公式) finalValue = (value - minV) / (maxV - minV) * 100.0; } else if (scaleType == 1) { // 对数刻度(匹配 QCPAxis::stLogarithmic) double logMin = log10(minV <= 0 ? 1 : minV); double logMax = log10(maxV); double logVal = log10(value); finalValue = (logVal - logMin) / (logMax - logMin) * 100.0; } else if (scaleType == 2) { // 倾角刻度(正切非线性,QCustomPlot没有,我们自己实现标准倾角) double PI = acos(-1); auto linearNorm = (value - minV) / (maxV - minV); // 0~1 double tanPos = tan(linearNorm * PI/2 - PI/4); // -1 ~ +1 double tanNorm = (tanPos + 1.0) / 2.0; // 0~1 finalValue = tanNorm * 100.0; } // 最终结果赋值给 lY2 lY2 = finalValue; qcpItemLine->start->setCoords(left_Low, lY1);//圆心位置 qcpItemLine->end->setCoords(right_Hight, lY2);//圆心位置 this->setCpCorrDepth(right_Hight); updateHandles(); //刷新,针对批量修改不在此处刷新,后面统一刷新 if(bReplot) { this->mPlot->replot(); } } // 获取当前范围 void TransparentDraggableCorePhysics::getRange() { m_left_Low = qcpItemLine->start->coords().x(); m_right_Hight = qcpItemLine->end->coords().x(); } // 设置矩形颜色 void TransparentDraggableCorePhysics::setColor(const QColor &color) { } // 删除框图 void TransparentDraggableCorePhysics::deleteRect() { if(mPlot) { mPlot->m_mapDraggable_Line.remove(m_strUuid); mPlot->removeItem(qcpItemLine); //mPlot->replot(); this->deleteLater(); } } void TransparentDraggableCorePhysics::update() { this->mPlot->replot(); } void TransparentDraggableCorePhysics::initRect() { // 连接鼠标事件 connect(mPlot, &QCustomPlot::mousePress, this, &TransparentDraggableCorePhysics::onMousePress); connect(mPlot, &QCustomPlot::mouseMove, this, &TransparentDraggableCorePhysics::onMouseMove); connect(mPlot, &QCustomPlot::mouseRelease, this, &TransparentDraggableCorePhysics::onMouseRelease); qcpItemLine = new QCPItemLine(mPlot); qcpItemLine->setLayer("overlay"); // 确保在最上层 //上下边界 updateHandles(); // 创建追踪点,自动跟随线条终点 tracer = new QCPItemTracer(this->mPlot); tracer->setGraph(nullptr); // 不关联曲线,自由定位 tracer->setStyle(QCPItemTracer::tsCircle); // 圆形,可选:tsSquare, tsCross, tsPlus等 tracer->setSize(3); // 点的大小(像素) tracer->setPen(QPen(Qt::black)); // 边框颜色 tracer->setBrush(QBrush(QColor(0, 0, 0, 0))); // 黄色半透明,Alpha=128 tracer->setInterpolating(false); // 绑定到线条终点(关键!) tracer->position->setParentAnchor(this->qcpItemLine->end); tracer->setVisible(false); qDebug() << "Creating qcpItemLine"; // qDebug() << "=========this:" << this << " mPlot:" << mPlot; } void TransparentDraggableCorePhysics::updateHandles() { } void TransparentDraggableCorePhysics::onDelRect() { //mDragMode = DragNone; //删除框图 deleteRect(); mPlot->replot(); } void TransparentDraggableCorePhysics::onMousePress(QMouseEvent *event) { if(event->button() != Qt::LeftButton)//右键 { // QMenu menu(nullptr); // QAction *delAction = menu.addAction("删除框图"); // connect(delAction, &QAction::triggered, this, &TransparentDraggableCorePhysics::onDelRect); // menu.exec(event->globalPos()); // return; } event->accept(); // 检查点击了哪个部分 double y = mPlot->xAxis->pixelToCoord(event->pos().y());//x轴展示深度 double x = mPlot->yAxis->pixelToCoord(event->pos().x()); //double lY1 = mPlot->yAxis->range().lower;//+10 double lY2 = mPlot->yAxis->range().upper; if(qcpItemLine->selectTest(event->pos(), false) < 5) { if(mPlot->m_SelectShiftLine) { //之前的选中线段,恢复黑色 TransparentDraggableCorePhysics *tmpLine = (TransparentDraggableCorePhysics*)mPlot->m_SelectShiftLine; QPen pen = tmpLine->qcpItemLine->pen(); // pen.setWidth(getCpLineWidth()); pen.setColor(this->getCpLineColor()); // 线宽 tmpLine->qcpItemLine->setPen(pen); // tmpLine->qcpItemLine->setPen(QPen(Qt::black)); } //重新设置选中线段 mPlot->m_SelectShiftLine = this; QPen pen = qcpItemLine->pen(); // pen.setWidth(getCpLineWidth()); pen.setColor(Qt::red); qcpItemLine->setPen(pen); double delta = (lY2-m_lY1)/10.0; if(x < m_lY1+delta) { mDragMode = DragLeft; } else if(x > lY2-delta) { mDragMode = DragRight; } else { mDragMode = DragRect; } } else { mDragMode = DragNone; return; } getRange(); mDragStartY = y; PropertyService()->initCorePhysicsItemProperty(this); } void TransparentDraggableCorePhysics::onMouseMove(QMouseEvent *event) { if(mDragMode == DragNone) return; event->accept(); //double x = mPlot->xAxis->pixelToCoord(event->pos().x()); //double dx = x - mDragStartX; double y = mPlot->xAxis->pixelToCoord(event->pos().y()); double dy = y - mDragStartY; mDragStartY = y; switch(mDragMode) { case DragLeft: { m_left_Low = m_left_Low + dy; break; } case DragRight: { m_right_Hight = m_right_Hight + dy; break; } case DragRect: { m_left_Low = m_left_Low + dy; m_right_Hight = m_right_Hight + dy; break; } default: break; } this->setRange(m_left_Low, m_left_Low,20,true); } void TransparentDraggableCorePhysics::onMouseRelease(QMouseEvent *event) { if(event->button() == Qt::LeftButton && mDragMode != DragNone) { event->accept(); //避免二次绘制框图 mPlot->m_bDrawRect = false; //emit rangeChanged(getRange()); mDragMode = DragNone; //取消选中状态 // QCPDataSelection emptySelection; // mPlot->graph(0)->setSelection(emptySelection); // mPlot->replot(); //取消选中框 mPlot->selectionRect()->cancel(); mPlot->replot(); mPlot->selectionRect()->mActive=true; // // 设置回选中之前的颜色 // this->setCpLineColor(this->getCpLineColor()); PropertyService()->initCorePhysicsItemProperty(this); // 保存slf文件 this->mPlot->saveToSLFCorePhysics(); } } int TransparentDraggableCorePhysics::getCpOrder() const { return this->m_cp_order; } void TransparentDraggableCorePhysics::setCpOrder(int value) { this->m_cp_order = value; } double TransparentDraggableCorePhysics::getCpDepth() const { return this->m_cp_depth; } void TransparentDraggableCorePhysics::setCpDepth(double value) { this->m_cp_depth = value; } double TransparentDraggableCorePhysics::getCpCorrDepth() const { return this->m_cp_corrDepth; } void TransparentDraggableCorePhysics::setCpCorrDepth(double value) { this->m_cp_corrDepth = value; } double TransparentDraggableCorePhysics::getCpCoreValue() const { return this->m_cp_coreValue; } void TransparentDraggableCorePhysics::setCpCoreValue(double value) { this->m_cp_coreValue = value; // 获取当前 end 点的坐标 double currentX = qcpItemLine->end->coords().x(); // 只修改 Y 坐标,X 保持不变 qcpItemLine->end->setCoords(currentX, value); } //double TransparentDraggableCorePhysics::getCpRotationAngle() const //{ // return this->m_cp_rotationAngle; //} //void TransparentDraggableCorePhysics::setCpRotationAngle(double value) //{ // this->m_cp_rotationAngle = value; //} //QString TransparentDraggableCorePhysics::getCpDisplayName() const //{ // return this->m_cp_displayName; //} //void TransparentDraggableCorePhysics::setCpDisplayName(const QString &value) //{ // this->m_cp_displayName = value; //} int TransparentDraggableCorePhysics::getCpLineWidth() const { return this->m_cp_lineWidth; } void TransparentDraggableCorePhysics::setCpLineWidth(int value) { this->m_cp_lineWidth = value; QPen pen = this->qcpItemLine->pen(); pen.setWidth(value); // 线宽 this->qcpItemLine->setPen(pen); } QColor TransparentDraggableCorePhysics::getCpLineColor() const { return this->m_cp_lineColor; } void TransparentDraggableCorePhysics::setCpLineColor(QColor value) { this->m_cp_lineColor = value; QPen pen = this->qcpItemLine->pen(); pen.setColor(value); this->qcpItemLine->setPen(pen); } Qt::PenStyle TransparentDraggableCorePhysics::getCpLineStyle() const { return this->m_cp_lineStyle; } void TransparentDraggableCorePhysics::setCpLineStyle(Qt::PenStyle value) { this->m_cp_lineStyle = value; QPen pen = this->qcpItemLine->pen(); pen.setStyle(value); this->qcpItemLine->setPen(pen); } double TransparentDraggableCorePhysics::getCpLeftScale() const { return this->m_cp_leftScale; } void TransparentDraggableCorePhysics::setCpLeftScale(double value) { this->m_cp_leftScale = value; // 重新绘制图形 this->setRange(this->m_left_Low, this->m_left_Low, this->getCpCoreValue(), false); } double TransparentDraggableCorePhysics::getCpRightScale() const { return this->m_cp_rightScale; } void TransparentDraggableCorePhysics::setCpRightScale(double value) { this->m_cp_rightScale = value; // 重新绘制图形 this->setRange(this->m_left_Low, this->m_left_Low, this->getCpCoreValue(), false); } int TransparentDraggableCorePhysics::getCpScaleType() const { return this->m_cp_scaleType; } void TransparentDraggableCorePhysics::setCpScaleType(int value) { this->m_cp_scaleType = value; // 重新绘制图形 this->setRange(this->m_left_Low, this->m_left_Low, this->getCpCoreValue(), false); } //int TransparentDraggableCorePhysics::getCpScaleDivisionsOrCustom() const //{ // return this->m_cp_scaleDivisionsOrCustom; //} //void TransparentDraggableCorePhysics::setCpScaleDivisionsOrCustom(int value) //{ // this->m_cp_scaleDivisionsOrCustom = value; //// // 创建文本刻度 Ticker //// QSharedPointer textTicker(new QCPAxisTickerText); //// double minVal = this->mPlot->yAxis2->range().lower; //// double maxVal = this->mPlot->yAxis2->range().upper; //// // 计算步长:(最大值 - 最小值) / 等分数 //// double step = (maxVal - minVal) / value; //// // 生成刻度 //// for (int i = 0; i <= value; ++i) { //// double value = minVal + step * i; //// // 取整显示(34.0 显示为 "34") //// QString label = QString::number(qRound(value)); //// textTicker->addTick(value, label); //// } //// // 应用 Ticker //// this->mPlot->yAxis2->setTicker(textTicker); //// // 设置范围(稍微留边距,让刻度显示完整) ////// this->mPlot->yAxis2->setRange(minVal - step * 0.1, maxVal + step * 0.1); //} QString TransparentDraggableCorePhysics::getCpDisplayUnit() const { return this->m_cp_displayUnit; } void TransparentDraggableCorePhysics::setCpDisplayUnit(const QString &value) { this->m_cp_displayUnit = value; } QString TransparentDraggableCorePhysics::getCpCurveName() const { return this->m_cp_curveName; } void TransparentDraggableCorePhysics::setCpCurveName(const QString &value) { this->m_cp_curveName = value; } QString TransparentDraggableCorePhysics::getCpCurveUnit() const { return this->m_cp_curveUnit; } void TransparentDraggableCorePhysics::setCpCurveUnit(const QString &value) { this->m_cp_curveUnit = value; } QFont TransparentDraggableCorePhysics::getCpCurveScale() const { return this->m_cp_curveScale; } void TransparentDraggableCorePhysics::setCpCurveScale(QFont value) { this->m_cp_curveScale = value; // this->mPlot->yAxis2->setTickLabelFont(value); } bool TransparentDraggableCorePhysics::getCpDrawAsBar() const { return this->m_cp_drawAsBar; } void TransparentDraggableCorePhysics::setCpDrawAsBar(bool value) { this->m_cp_drawAsBar = value; if(value) { QPen pen = this->qcpItemLine->pen(); pen.setColor(this->getCpLineColor()); // 完全透明 this->qcpItemLine->setPen(pen); } else { QPen pen = this->qcpItemLine->pen(); pen.setColor(QColor(0,0,0,0)); // 完全透明 this->qcpItemLine->setPen(pen); } } bool TransparentDraggableCorePhysics::getCpLeftBoundary() const { return this->m_cp_leftBoundary; } void TransparentDraggableCorePhysics::setCpLeftBoundary(bool value) { this->m_cp_leftBoundary = value; // 由于 X轴↔Y轴 互换,"水平翻转"变成关于 Y轴中心对称 double y_center = (this->mPlot->yAxis->range().lower + this->mPlot->yAxis->range().upper) / 2; // 获取原坐标(注意:此时 coords() 返回的是互换后的坐标) QPointF start = this->qcpItemLine->start->coords(); QPointF end = this->qcpItemLine->end->coords(); // 翻转:Y轴不变(实际是视觉上的X轴),X轴镜像(实际是视觉上的Y轴) // 但由于轴互换了,我们需要翻转的是 y 坐标 this->qcpItemLine->start->setCoords(start.x(), 2 * y_center - start.y()); this->qcpItemLine->end->setCoords(end.x(), 2 * y_center - end.y()); } bool TransparentDraggableCorePhysics::getCpSkipZeroInvalidValues() const { return this->m_cp_skipZeroInvalidValues; } void TransparentDraggableCorePhysics::setCpSkipZeroInvalidValues(bool value) { this->m_cp_skipZeroInvalidValues = value; } bool TransparentDraggableCorePhysics::getCpDrawEnvelope() const { return this->m_cp_drawEnvelope; } void TransparentDraggableCorePhysics::setCpDrawEnvelope(bool value) { this->m_cp_drawEnvelope = value; } bool TransparentDraggableCorePhysics::getCpDrawAsDot() const { return this->m_cp_drawAsDot; } void TransparentDraggableCorePhysics::setCpDrawAsDot(bool value) { this->m_cp_drawAsDot = value; // 获取所有 QCPItemTracer(包括子对象的子对象) QList tracers = this->mPlot->findChildren(); foreach (QCPItemTracer *tracer, tracers) { // 处理每个 tracer tracer->setVisible(value); // 例如:全部隐藏 } } int TransparentDraggableCorePhysics::getCpSymbolType() const { return this->m_cp_symbolType; } void TransparentDraggableCorePhysics::setCpSymbolType(int value) { this->m_cp_symbolType = value; QList tracers = this->mPlot->findChildren(); foreach (QCPItemTracer *tracer, tracers) { switch(value) { case 0: // 圆形 tracer->setStyle(QCPItemTracer::tsCircle); break; case 1: // 矩形 tracer->setStyle(QCPItemTracer::tsSquare); // ■ 方形(不是矩形) break; case 2: // 三角 tracer->setStyle(QCPItemTracer::tsSquare); break; case 3: // 菱形 tracer->setStyle(QCPItemTracer::tsSquare); break; } } } QColor TransparentDraggableCorePhysics::getCpSymbolBorderColor() const { return this->m_cp_symbolBorderColor; } void TransparentDraggableCorePhysics::setCpSymbolBorderColor(QColor value) { this->m_cp_symbolBorderColor = value; QList tracers = this->mPlot->findChildren(); foreach (QCPItemTracer *tracer, tracers) { // 获取当前的 pen QPen currentPen = tracer->pen(); // 只修改颜色,保留其他属性(宽度、样式等) currentPen.setColor(value); // 修改颜色 // 设置回去 tracer->setPen(currentPen); } } int TransparentDraggableCorePhysics::getCpSymbolSize() const { return this->m_cp_symbolSize; } void TransparentDraggableCorePhysics::setCpSymbolSize(int value) { this->m_cp_symbolSize = value; QList tracers = this->mPlot->findChildren(); foreach (QCPItemTracer *tracer, tracers) { tracer->setSize(value); // 点的大小(像素) } } QColor TransparentDraggableCorePhysics::getCpSymbolFillColor() const { return this->m_cp_symbolFillColor; } void TransparentDraggableCorePhysics::setCpSymbolFillColor(QColor value) { this->m_cp_symbolFillColor = value; QList tracers = this->mPlot->findChildren(); foreach (QCPItemTracer *tracer, tracers) { // 获取当前 brush QBrush currentBrush = tracer->brush(); // 只修改颜色,保留其他属性(填充样式、纹理等) currentBrush.setColor(value); // 修改填充颜色 // 设置回去 tracer->setBrush(currentBrush); } } int TransparentDraggableCorePhysics::getCpFieldName() const { return this->m_cp_fieldName; } void TransparentDraggableCorePhysics::setCpFieldName(const int &value) { this->m_cp_fieldName = value; }