Java中使用SWT在Canvas绘制XY图表 解决刻度消失、末端不绘制问题
问题根因
- 整数除法精度丢失:你使用int类型计算
step_x,当列表长度大于等于画布宽度时,canvas.getClientArea().width / list.size()的整数除法结果直接为0,循环判断条件step_x > 0不满足,直接终止绘制逻辑,刻度自然全部消失。 - 刻度与数据点强绑定逻辑不合理:当前逻辑每一个数据点对应一个待绘制刻度,数据量上涨后相邻刻度的间距小于文本宽度,重叠校验会把所有后续刻度都跳过,最终只剩前几个甚至完全没有刻度。
- 并发读写冲突:数据添加操作在并行线程执行,绘制线程读取列表、计算
step_x的过程中可能出现列表长度不一致的问题,要么计算的step_x和实际遍历的数据量不匹配,要么遍历列表时抛出并发修改异常,最终导致末端数据绘制异常。 - 循环逻辑缺陷:
step_x变小后,循环累加i的步长太小,当数据量极大时i的累加速度跟不上列表遍历速度,会出现列表遍历完了i还没到画布末端,或者i溢出变成负数的情况,导致末端数据没有正常绘制。
修复方案
1. 优化刻度生成逻辑,解除与数据点的绑定
固定横向显示的刻度上限,比如最多显示8~10个时间刻度,不管数据量多少,只按均匀间隔取刻度点,避免数据量上涨后刻度挤在一起:
// 固定最多显示10个刻度,可根据画布宽度动态调整 int maxNotchCount = 10; int actualNotchCount = Math.min(maxNotchCount, drawList.size()); for (int n = 0; n < actualNotchCount; n++) { // 按间隔取对应的数据点作为刻度锚点 int dataIndex = n * drawList.size() / actualNotchCount; GraphData data = drawList.get(dataIndex); // 计算刻度的x坐标 int x = client_area.x + (int) (dataIndex * stepX); String notchString = returnTime(data); int notchWidth = a_gc.stringExtent(notchString).x; int curBegX = x - notchWidth / 2; if (prevEndX < curBegX) { a_gc.drawLine(x, client_area.y, x, client_area.height); a_gc.drawString(notchString, curBegX, convertGraphtoLeftBotCorner(client_area.y + NOTCH_LENGTH, a_canvas)); prevEndX = curBegX + notchWidth; } }
2. 修正步长计算逻辑,避免整数除法为0
用浮点数计算步长,绘制的时候再转成int,同时设置最小步长为1,避免步长为0导致循环终止:
// 并行线程中计算步长,用float类型存储 float stepX = (float) canvas.getClientArea().width / Math.max(1, list.size());
3. 增加并发读写保护
给列表的读写操作加锁,或者每次添加数据后复制一份副本给绘制线程用,避免并发修改问题:
// 并行线程添加数据时加锁 synchronized (list) { list.add(newData); stepX = (float) canvas.getClientArea().width / list.size(); } // 绘制线程读取数据前先复制副本,避免绘制过程中列表被修改 List<GraphData> drawList; synchronized (list) { drawList = new ArrayList<>(list); } // 后续所有绘制逻辑都使用drawList,不直接操作原列表
4. 优化循环逻辑,确保末端数据绘制
把原来的i累加循环改成按数据索引遍历,计算每个数据点的x坐标,避免步长太小导致i累加不及时:
float stepX = (float) client_area.width / Math.max(1, drawList.size()); for (int idx = 0; idx < drawList.size(); idx++) { int x = client_area.x + (int)(idx * stepX); // 绘制数据点的逻辑使用该x坐标即可 }
内容的提问来源于stack exchange,提问作者Valdemar
相关产品推荐
相关产品推荐

