|
|
#ifndef NMWXCHARTWIDGET_H
|
|
|
#define NMWXCHARTWIDGET_H
|
|
|
|
|
|
#include <QWidget>
|
|
|
#include <QVector>
|
|
|
#include <QPointF>
|
|
|
#include <QRectF>
|
|
|
#include "nmDataPerforation.h"
|
|
|
|
|
|
class QPainter;
|
|
|
class QMouseEvent;
|
|
|
class QPaintEvent;
|
|
|
|
|
|
class nmWxChartWidget : public QWidget
|
|
|
{
|
|
|
Q_OBJECT
|
|
|
|
|
|
public:
|
|
|
explicit nmWxChartWidget(QWidget *parent = 0);
|
|
|
virtual ~nmWxChartWidget();
|
|
|
|
|
|
protected:
|
|
|
virtual void paintEvent(QPaintEvent *event);
|
|
|
virtual void mousePressEvent(QMouseEvent *event);
|
|
|
virtual void mouseMoveEvent(QMouseEvent *event);
|
|
|
virtual void mouseReleaseEvent(QMouseEvent *event);
|
|
|
|
|
|
public:
|
|
|
// 设置skin值
|
|
|
void setSkinValues(double bValue, double kValue);
|
|
|
|
|
|
// 设置和获取线条位置
|
|
|
void setLinePositions(double x1, double y1, double x2, double y2);
|
|
|
void getLinePositions(double& x1, double& y1, double& x2, double& y2) const;
|
|
|
|
|
|
// 获取计算出的skin值
|
|
|
double getSkin0Value() const;
|
|
|
double getDSkinDqValue() const;
|
|
|
|
|
|
bool getLassoMode() const;
|
|
|
void setLassoMode(bool enabled);
|
|
|
|
|
|
// 重置线条到初始位置
|
|
|
void resetLinesToInitialPositions();
|
|
|
|
|
|
// 新增:设置流动段数据和流量数据
|
|
|
void setFlowSegmentData(const nmDataPerforation& perforationData);
|
|
|
void setFlowData(const QVector<QPointF>& flowData);
|
|
|
void setRawFlowData(const QVector<QPointF>& rawFlowData);
|
|
|
void setSnapToRateChanges(bool snapToRateChanges);
|
|
|
|
|
|
// 新增:更新×标记点数据
|
|
|
void updateCrossMarkPoints();
|
|
|
// 重置所有×标记点
|
|
|
void resetAllCrossMarks();
|
|
|
|
|
|
void updateCrossMarkPointsData(); // 只更新现有×标记点的数据
|
|
|
void regenerateCrossMarkPoints(); // 完全重新生成×标记点
|
|
|
|
|
|
// 计算方法
|
|
|
void calculateAverageValue();
|
|
|
bool shouldShowAverageLine();
|
|
|
void calculateDataRange(); // 动态计算坐标范围
|
|
|
|
|
|
signals:
|
|
|
void skinValuesChanged(double skin0Value, double dSkinDqValue);
|
|
|
void crossMarksFiltered(); // 当×标记被过滤后发出的信号
|
|
|
void lassoOperationCompleted(); // 新增:套索操作完成信号
|
|
|
|
|
|
private:
|
|
|
// 绘制方法
|
|
|
void drawGrid(QPainter &painter);
|
|
|
void drawAxes(QPainter &painter);
|
|
|
void drawLine(QPainter &painter);
|
|
|
void drawPoints(QPainter &painter);
|
|
|
void drawAverageLine(QPainter &painter); // 绘制skin0线
|
|
|
void drawCrossMarks(QPainter &painter); // 新增:绘制×标记
|
|
|
|
|
|
// 坐标转换
|
|
|
QPointF dataToScreen(const QPointF &dataPoint);
|
|
|
QPointF screenToData(const QPointF &screenPoint);
|
|
|
|
|
|
// 交互相关
|
|
|
int findNearestPoint(const QPointF &screenPos);
|
|
|
bool isNearLine(const QPointF &screenPos);
|
|
|
|
|
|
// 辅助方法
|
|
|
void setLinePositionsFromSkinValues(double skin0Value, double dSkinDqValue);
|
|
|
double getAverageFlowRateForSegment(double segmentStartTime, double segmentEndTime) const;
|
|
|
|
|
|
// 最小二乘法拟合×标记点,返回拟合是否成功
|
|
|
bool fitLineToPoints();
|
|
|
|
|
|
// 计算拟合直线的参数 y = ax + b
|
|
|
void calculateLinearRegression(const QVector<QPointF>& points, double& slope, double& intercept);
|
|
|
|
|
|
// 根据拟合结果设置红色线的端点位置
|
|
|
void setFittedLinePositions(double slope, double intercept);
|
|
|
|
|
|
// 套索相关方法
|
|
|
bool isPointInPolygon(const QPointF& point, const QPolygonF& polygon);
|
|
|
void deleteSelectedCrossMarks();
|
|
|
void drawLasso(QPainter& painter);
|
|
|
void clearLassoSelection();
|
|
|
void exitLassoMode();
|
|
|
|
|
|
// 常量定义
|
|
|
static const double POINT_RADIUS;
|
|
|
static const double POINT_CLICK_RADIUS;
|
|
|
static const double LINE_CLICK_DISTANCE;
|
|
|
static const double CROSS_MARK_SIZE; // 新增:×标记大小
|
|
|
|
|
|
QVector<QPointF> linePoints; // 红线端点
|
|
|
QVector<QPointF> initialPositions; // 初始位置(现在动态计算)
|
|
|
QVector<QPointF> crossMarkPoints; // 新增:×标记点位置
|
|
|
QVector<int> crossMarkSegmentIndices; // 新增:×标记对应的段索引
|
|
|
|
|
|
QRectF dataRect;
|
|
|
QRectF chartRect;
|
|
|
|
|
|
bool isDragging;
|
|
|
bool isDraggingLine;
|
|
|
int dragPointIndex;
|
|
|
QPointF lastMousePos;
|
|
|
QPointF dragOffset;
|
|
|
|
|
|
bool showAverageLine; // 是否显示skin0线
|
|
|
double averageValue; // skin0值(y轴截距)
|
|
|
double dSkinDqValue; // 斜率
|
|
|
double selectionRangeX1; // 选择范围的左端点x值
|
|
|
double selectionRangeX2; // 选择范围的右端点x值
|
|
|
|
|
|
// 数据源
|
|
|
nmDataPerforation m_perforationData;
|
|
|
QVector<QPointF> m_flowData; // 流量数据
|
|
|
QVector<QPointF> m_rawFlowData;
|
|
|
|
|
|
bool m_snapToRateChanges; // 保存对齐到流量段的状态
|
|
|
|
|
|
// 套索选择相关
|
|
|
bool m_lassoMode; // 是否处于套索模式
|
|
|
bool m_lassoDrawing; // 是否正在绘制套索
|
|
|
QPolygonF m_lassoPath; // 套索路径
|
|
|
QVector<int> m_selectedCrossMarkIndices; // 选中的×标记索引
|
|
|
bool m_hasPerformedInitialFit; // 是否已经进行过初始拟合
|
|
|
|
|
|
};
|
|
|
|
|
|
#endif // NMWXCHARTWIDGET_H
|