实验性功能新增「均值滤波」+ 构建为新信号
- 「实验性功能」二级菜单新增带勾选的「均值滤波」:开启后为本网格每条信号叠加绘制
一条 N 点滑动平均曲线,算法与「边沿计数(中心轴)」的中心平均值曲线**完全一致**
(同一实现 ComputeMovingAverage),配色同样由信号色派生为高对比度颜色、透明度一致。
- 新增均值滤波浮动面板:标题栏可拖拽、✕ 关闭,面板内列出被处理的信号名、
「均值点数 N」内联编辑行,以及底部的「构建为新信号」按钮(悬停高亮 + 手型光标)。
- 「构建为新信号」:把滤波后的曲线作为新信号插入,命名为「<原信号名称> (N点均值)」,
归属到原信号所属组的原信号位置**下方**,成为独立的新信号;其所在网格也移动到
原信号网格的下方。合并网格时一次按钮为该网格内每条可见信号各构建一条。
为此新增 DataSet::InsertDerivedSignal / TabConfig::RemapAfterSignalInsert /
TabConfig::MoveLaneOfSignalBelow / TabConfig::RenameLanes(插入位置之后的信号引用
与可见性列同步重映射)。
- 光标交互与「边沿计数(中心轴)」同构:光标处标注均值滤波曲线的取值
与双光标增量,文案为「值(均值滤波)」/「值(+增量 均值滤波)」;
两条派生曲线的取值胶囊已抽成同一段绘制逻辑。
- 浮动面板种类由 bool centerAxis 改为 EdgePanelKind{COUNT,CENTER,MEAN},
布局/宽度/命中测试/绘制统一走同一套几何。
- 以 VERY_BIG_DATA.CSV 验证:曲线预览、N 编辑、双光标取值标注、
单信号与合并网格两种情况下的新信号命名与插入位置均正确。
This commit is contained in:
1 parent
8ae8d7af4f
commit
f5028b1e18
6 files changed
+885
-210
No files matched your search
@@ -53,7 +53,8 @@ namespace jdi
|
||||
LANE_Y_MAX, /**< 编辑某网格的 Y 轴最大值。 */
|
||||
LANE_Y_MIN, /**< 编辑某网格的 Y 轴最小值。 */
|
||||
SIGNAL_NAME, /**< 编辑图例中某信号的显示名称。 */
|
||||
EDGE_CENTER_SMOOTH /**< 编辑「中心轴边沿计数」的平滑点数 N。 */
|
||||
EDGE_CENTER_SMOOTH, /**< 编辑「中心轴边沿计数」的平滑点数 N。 */
|
||||
MEAN_FILTER_RADIUS /**< 编辑「均值滤波」的均值点数 N。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,7 +70,18 @@ namespace jdi
|
||||
PLOT_CMD_LANE_AUTO_VIEW = 6, /**< 切换本网格的「选区 Y 轴自适应」开关。 */
|
||||
PLOT_CMD_LANE_EDGE_COUNT = 7, /**< 切换本网格的「实验性功能 → 边沿计数」开关。 */
|
||||
PLOT_CMD_LANE_EDGE_CENTER = 8, /**< 切换本网格的「实验性功能 → 边沿计数(中心轴)」开关。 */
|
||||
PLOT_CMD_LANE_SPLIT = 9 /**< 拆分当前网格:把网格内信号按个拆成独立网格并顺次下移编号。 */
|
||||
PLOT_CMD_LANE_SPLIT = 9, /**< 拆分当前网格:把网格内信号按个拆成独立网格并顺次下移编号。 */
|
||||
PLOT_CMD_LANE_MEAN_FILTER = 10 /**< 切换本网格的「实验性功能 → 均值滤波」开关。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 实验性功能浮动面板的种类。
|
||||
*/
|
||||
enum class EdgePanelKind : int
|
||||
{
|
||||
COUNT = 0, /**< 边沿计数。 */
|
||||
CENTER = 1, /**< 边沿计数(中心轴)。 */
|
||||
MEAN = 2 /**< 均值滤波。 */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -462,6 +474,40 @@ namespace jdi
|
||||
*/
|
||||
bool ToggleLaneEdgeCenterCount(int laneIndex);
|
||||
|
||||
/**
|
||||
* @brief 判断某网格是否开启了「实验性功能 → 均值滤波」。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 开启返回 true。
|
||||
*/
|
||||
bool LaneMeanFilter(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 设置某网格的「均值滤波」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] enabled 目标状态。
|
||||
* @return 状态发生变化返回 true。
|
||||
*/
|
||||
bool SetLaneMeanFilter(int laneIndex, bool enabled);
|
||||
|
||||
/**
|
||||
* @brief 切换某网格的「均值滤波」开关。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 切换后的状态。
|
||||
*/
|
||||
bool ToggleLaneMeanFilter(int laneIndex);
|
||||
|
||||
/**
|
||||
* @brief 取出「构建为新信号」请求(由面板底部按钮触发)。
|
||||
*
|
||||
* 请求只描述「哪一网格、用多大的 N」,真正的信号构建与插入由宿主(Application)
|
||||
* 完成——数据层属于 DataSet,绘图区不能直接修改它。
|
||||
*
|
||||
* @param [OUT] laneIndex 触发该请求的网格下标。
|
||||
* @param [OUT] radius 均值滤波半径 N。
|
||||
* @return 存在待处理请求返回 true(取出后清空)。
|
||||
*/
|
||||
bool TakePendingMeanFilterBuild(int& laneIndex, int& radius);
|
||||
|
||||
/**
|
||||
* @brief 进入某网格 Y 轴上限/下限的内联输入状态。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
@@ -913,7 +959,7 @@ namespace jdi
|
||||
bool IsOnEdgeCursorLine(int x, int y, int& laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 实验性功能浮动面板的几何布局(边沿计数 / 中心轴边沿计数共用同一套样式)。
|
||||
* @brief 实验性功能浮动面板的几何布局(三类面板共用同一套样式)。
|
||||
*/
|
||||
struct EdgePanelLayout
|
||||
{
|
||||
@@ -921,16 +967,17 @@ namespace jdi
|
||||
gd::RectF title; /**< 标题栏(**唯一可拖拽区域**)。 */
|
||||
gd::RectF close; /**< ✕ 关闭按钮。 */
|
||||
gd::RectF edit; /**< 面板底部编辑行(无编辑内容时宽度为 0)。 */
|
||||
gd::RectF button; /**< 面板底部按钮(无按钮时宽度为 0)。 */
|
||||
int rows = 0; /**< 统计行数(每条可见信号一行)。 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 计算某个实验性功能面板的布局。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] centerAxis 为 true 时取「边沿计数(中心轴)」面板,否则取「边沿计数」。
|
||||
* @param [IN] kind 面板种类。
|
||||
* @return 布局;面板未展开时各项均为空矩形。
|
||||
*/
|
||||
EdgePanelLayout EdgePanelLayoutFor(int laneIndex, bool centerAxis) const;
|
||||
EdgePanelLayout EdgePanelLayoutFor(int laneIndex, EdgePanelKind kind) const;
|
||||
|
||||
/**
|
||||
* @brief 获取「边沿计数(中心轴)」浮动面板的矩形。
|
||||
@@ -984,6 +1031,28 @@ namespace jdi
|
||||
void PaintCenterCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int smooth) const;
|
||||
|
||||
/**
|
||||
* @brief 绘制某条信号的均值滤波曲线(与中心平均值曲线同一算法与同一配色派生规则)。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
* @param [IN] resolved 信号视图。
|
||||
* @param [IN] lane 网格绘制信息。
|
||||
* @param [IN] radius 均值滤波半径 N。
|
||||
*/
|
||||
void PaintMeanFilterCurve(gd::Graphics& g, const ResolvedSignal& resolved, const LaneVisual& lane,
|
||||
int radius) const;
|
||||
|
||||
/**
|
||||
* @brief 取某个时刻的均值滤波曲线取值(用于纵向光标的取值标注)。
|
||||
* @param [IN] file 信号所属文件。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [IN] radius 均值滤波半径 N。
|
||||
* @param [IN] time 采样时刻。
|
||||
* @param [OUT] value 输出取值。
|
||||
* @return 取到有效值返回 true。
|
||||
*/
|
||||
bool MeanFilterValueAt(const DataFile& file, const SignalData& signal, int radius, double time,
|
||||
double& value) const;
|
||||
|
||||
/**
|
||||
* @brief 数据点标记的位置与"越界方向"(用于决定画圆点还是贴边三角)。
|
||||
*/
|
||||
@@ -1066,10 +1135,10 @@ namespace jdi
|
||||
/**
|
||||
* @brief 计算实验性功能面板所需的宽度(排版与绘制共用,保证文字完整不被省略)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @param [IN] centerAxis 为 true 时取「边沿计数(中心轴)」面板。
|
||||
* @param [IN] kind 面板种类。
|
||||
* @return 面板宽度(像素)。
|
||||
*/
|
||||
float EdgePanelWidth(int laneIndex, bool centerAxis) const;
|
||||
float EdgePanelWidth(int laneIndex, EdgePanelKind kind) const;
|
||||
|
||||
/**
|
||||
* @brief 判断边沿统计是否限定在双光标区间内(双光标模式)。
|
||||
@@ -1205,6 +1274,9 @@ namespace jdi
|
||||
std::wstring m_pendingRenameName; /**< 待宿主窗口应用的信号新名称。 */
|
||||
bool m_pendingRename = false; /**< 是否存在待应用的重命名请求。 */
|
||||
|
||||
int m_pendingMeanFilterLane = -1; /**< 待构建的均值滤波信号所属网格下标(-1 表示无请求)。 */
|
||||
int m_pendingMeanFilterRadius = 0; /**< 待构建的均值滤波半径 N。 */
|
||||
|
||||
int m_hoverLane = -1; /**< 当前悬停网格下标。 */
|
||||
int m_mouseX = 0; /**< 最近一次鼠标横坐标(用于悬停提示定位)。 */
|
||||
int m_mouseY = 0; /**< 最近一次鼠标纵坐标(用于悬停提示定位)。 */
|
||||
@@ -1257,7 +1329,7 @@ namespace jdi
|
||||
// 「边沿计数」横向光标 / 面板的拖拽状态。
|
||||
int m_edgeDragLane = -1; /**< 正在拖动的横向光标所属网格。 */
|
||||
int m_edgePanelDragLane = -1; /**< 正在拖动的统计面板所属网格。 */
|
||||
bool m_edgePanelDragCenter = false; /**< 正在拖动的面板是否为「中心轴边沿计数」面板。 */
|
||||
EdgePanelKind m_edgePanelDragKind = EdgePanelKind::COUNT; /**< 正在拖动的面板种类。 */
|
||||
gd::PointF m_edgePanelDragOffset; /**< 抓取面板时的相对偏移(保持不跳变)。 */
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user