You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Include/nmNum/nmSubWxs/nmWxChartWidget.h

150 lines
4.6 KiB
C

#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