绘图区交互修正:悬停不改光标、图例联动、时间轴子刻度、边沿计数规则与光标区间联动
- 网格内信号悬停不再改变鼠标光标(维持原始箭头);只有真正按下拖动(MOVE_SIGNAL)
时才切换为抓握光标。
- 修复网格左上角图例的联动缺陷:
* 根因是图例的选中/悬停底色绘制在静态场景缓存里,而缓存指纹(SceneContentHash)
未包含「选中信号」→ 在左侧信号面板点选信号后缓存未失效,图例不会高亮。
现在把 SelectedRef() 折叠进指纹,选中变化会正确重绘。
* 图例悬停态随鼠标变化,不能进缓存:新增 m_hoverLegend 与 PaintLegendHighlight(),
在静态场景贴图之后用半透明强调色叠在本条目上形成“半高亮”,并在两条绘制路径
(缓存贴图快路径 / 整幅重绘路径)中都调用。
* 悬停图例时不再触发曲线拖拽提示(不画信号光晕、不弹“按住拖拽可移入其它网格”气泡),
仅半高亮;点选后参与联动。
- 主时间轴新增五等分子刻度线:在相邻主刻度之间插入 4 条短刻度(3px),
与主刻度重合的位置跳过。
- 「实验性功能 → 边沿计数」按用户明确的规则重做统计:
* 判定改为“穿越横向光标所在的 Y 值”:信号从下往上穿越 → 上升沿,
从上往下穿越 → 下降沿(原先按信号幅值中点判定,与光标无关,因此拖动光标
结果不变)。
* 缓存键随之扩展为「文件 + 信号 + 横向光标幅值 + 时间区间」,
拖动横向光标或拖动时间光标都会重算。
* 时间单调时二分定位采样区间,非单调时按区间过滤;NaN 仍视为断点。
* 面板宽度改为按文本实测宽度(EdgePanelWidth,使用不含省略号的
UiMeasureTextWidth)自适应,名称与“上升沿 N / 下降沿 M”一律完整显示,
数字不再被省略或截断。
* 点击 ✕ 现在同时关闭该网格的边沿计数功能(横向光标一并消失),
不再是仅收起面板。
- 边沿计数与光标功能联动:双光标模式下面板标题追加尾缀“(光标区间内)”,
统计只覆盖左右光标之间的时间区间;区间端点始终取两条光标时间的较小/较大值,
因此把任一光标拖到另一侧(左右交换)后区间与计数依然正确。
验证(TestData/VERY_BIG_DATA.CSV,编码器A相,125%、1725x996):
- 光标形态:悬停曲线 = ARROW(不改变);拖拽 = SIZEALL。
- 图例联动:在左侧面板点选信号后图例条目正确高亮;悬停图例显示半高亮、
无拖拽提示气泡。
- 时间轴五等分子刻度可见。
- 边沿计数(用独立脚本 .preflight/edgeprobe2.ps1 / edgeprobe3.ps1 按同一规则复算,
与界面显示逐位一致):
* 阈值 2.54415(全区间)→ 界面/复算均 上升沿 1333422 下降沿 1333421;
拖动横向光标到 5.08994 → 界面/复算均 上升沿 1843881 下降沿 1843881(计数随光标变化);
阈值 100 → 0 / 0。
* 双光标区间 [48.0211, 64.4051] → 界面/复算均 上升沿 193161 下降沿 193161;
区间 [64.4051, 79.8623] → 163647 / 163647。
* 光标交换:把光标 1 的时间改为 120(越过光标 2 的 79.8623)后,Δt 变为
40s 137.726ms,面板标题为“边沿计数(光标区间内)”,
计数 404668 / 404669 与复算的区间 [79.8623, 120] 完全一致。
- ✕:面板与横向光标同时消失。
- 回归:[1].CSV 双光标正常(Δt:151ms 200us),面板标题带尾缀;
make clean && make all 无警告无错误。
This commit is contained in:
1 parent
cd6e0ed058
commit
b884e7ecb4
2 files changed
+275
-39
No files matched your search
@@ -870,14 +870,50 @@ namespace jdi
|
||||
gd::RectF EdgePanelCloseRect(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 统计某信号的上/下边沿数量(以信号幅值中点为判定阈值),结果带缓存。
|
||||
* @brief 统计某信号穿越横向光标幅值的上/下边沿数量,结果带缓存。
|
||||
* @param [IN] file 信号所属文件。
|
||||
* @param [IN] signal 目标信号。
|
||||
* @param [OUT] rising 上升沿数量。
|
||||
* @param [OUT] falling 下降沿数量。
|
||||
* @param [IN] edgeValue 横向光标所在的幅值。
|
||||
* @param [IN] hasRange 是否只统计某个时间区间(双光标模式下为光标区间)。
|
||||
* @param [IN] rangeMin 区间左端点时间。
|
||||
* @param [IN] rangeMax 区间右端点时间。
|
||||
* @param [OUT] rising 上升沿数量(从下往上穿越)。
|
||||
* @param [OUT] falling 下降沿数量(从上往下穿越)。
|
||||
*/
|
||||
void EdgeCountsFor(const DataFile& file, const SignalData& signal, std::size_t& rising,
|
||||
std::size_t& falling);
|
||||
void EdgeCountsFor(const DataFile& file, const SignalData& signal, double edgeValue,
|
||||
bool hasRange, double rangeMin, double rangeMax, std::size_t& rising,
|
||||
std::size_t& falling) const;
|
||||
|
||||
/**
|
||||
* @brief 计算边沿统计面板所需的宽度(排版与绘制共用,保证文字完整不被省略)。
|
||||
* @param [IN] laneIndex 网格下标。
|
||||
* @return 面板宽度(像素)。
|
||||
*/
|
||||
float EdgePanelWidth(int laneIndex) const;
|
||||
|
||||
/**
|
||||
* @brief 判断边沿统计是否限定在双光标区间内(双光标模式)。
|
||||
* @return 限定在光标区间内返回 true。
|
||||
*/
|
||||
bool EdgeRangeActive() const;
|
||||
|
||||
/**
|
||||
* @brief 边沿统计时间区间的左端点(取两条光标的较小时间)。
|
||||
* @return 区间左端点。
|
||||
*/
|
||||
double EdgeRangeMin() const;
|
||||
|
||||
/**
|
||||
* @brief 边沿统计时间区间的右端点(取两条光标的较大时间)。
|
||||
* @return 区间右端点。
|
||||
*/
|
||||
double EdgeRangeMax() const;
|
||||
|
||||
/**
|
||||
* @brief 双光标模式下面板标题的尾缀文本(“(光标区间内)”)。
|
||||
* @return 尾缀文本,非双光标模式返回空串。
|
||||
*/
|
||||
std::wstring EdgeRangeSuffix() const;
|
||||
|
||||
/**
|
||||
* @brief 绘制拖动中的缩放选区。
|
||||
@@ -967,6 +1003,7 @@ namespace jdi
|
||||
gd::RectF m_rubberRect; /**< 拖拽选区矩形。 */
|
||||
|
||||
SignalRef m_hoverSignal; /**< 鼠标悬停命中的信号(曲线高亮)。 */
|
||||
SignalRef m_hoverLegend; /**< 鼠标悬停命中的图例条目(半高亮提示,不触发曲线拖拽提示)。 */
|
||||
SignalRef m_dragSignal; /**< 正在被拖拽的信号。 */
|
||||
int m_dragTargetLane = -1; /**< 拖拽信号时的目标网格下标。 */
|
||||
int m_dragMouseX = 0; /**< 拖拽过程中鼠标的当前横坐标(虚影跟随)。 */
|
||||
@@ -999,15 +1036,19 @@ namespace jdi
|
||||
std::vector<gd::RectF> m_cursorLabelRects; /**< 本次绘制已占用的取值标注矩形(用于避让重叠)。 */
|
||||
std::vector<LaneVisual> m_lanes; /**< 当前网格绘制信息集合。 */
|
||||
|
||||
/** 边沿统计结果缓存项(按「文件指针 + 信号指针」标识,数据变化时整体失效)。 */
|
||||
/** 边沿统计结果缓存项(按「文件 + 信号 + 横向光标幅值 + 时间区间」标识,任一变化即重算)。 */
|
||||
struct EdgeCountEntry
|
||||
{
|
||||
const DataFile* file = nullptr;
|
||||
const SignalData* signal = nullptr;
|
||||
double edgeValue = 0.0;
|
||||
bool hasRange = false;
|
||||
double rangeMin = 0.0;
|
||||
double rangeMax = 0.0;
|
||||
std::size_t rising = 0;
|
||||
std::size_t falling = 0;
|
||||
};
|
||||
std::vector<EdgeCountEntry> m_edgeCountCache; /**< 边沿统计缓存。 */
|
||||
mutable std::vector<EdgeCountEntry> m_edgeCountCache; /**< 边沿统计缓存(纯缓存,逻辑上不影响对象状态)。 */
|
||||
|
||||
// 「边沿计数」横向光标 / 面板的拖拽状态。
|
||||
int m_edgeDragLane = -1; /**< 正在拖动的横向光标所属网格。 */
|
||||
@@ -1124,6 +1165,12 @@ namespace jdi
|
||||
*/
|
||||
void PaintHoverHighlight(gd::Graphics& g);
|
||||
|
||||
/**
|
||||
* @brief 绘制图例条目的悬停半高亮提示(在静态场景贴图之后绘制)。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
*/
|
||||
void PaintLegendHighlight(gd::Graphics& g);
|
||||
|
||||
/**
|
||||
* @brief 绘制某条信号的悬停/拖拽光晕。
|
||||
* @param [IN,OUT] g 绘图上下文。
|
||||
|
||||
Reference in new issue
Block a user