我的代码在面板中绘制了5000个时间序列数据点,默认宽度为581像素,但当用户调整窗口大小时,宽度会发生变化。我的代码还绘制了几个矩形标记,每个标记在相同的空间中标识一个局部最大值/峰值。Java中时间序列数据中用户选择的标记
我需要让用户右键单击任何矩形峰标记,以便用户可以手动删除任何假峰。问题在于,当用户右键单击峰标记时,我的代码报告的x坐标不同于预期值。我怀疑这个原因可能与将581个x像素转换回5000个数据索引时的舍入误差有关。但我不确定原因。
任何人都可以提出一个解决方案,使我的用户可以通过右键单击来手动选择上述峰值标记之一吗?
我附上下面的代码的相关部分。我的实际代码非常非常长,而且太复杂,无法发布。但是下面的相关部分应该足以让某人看到我的方法的逻辑,然后提出一个更有效的方法。
声明所涉及的类的代码是:
class SineDraw extends JPanel implements MouseMotionListener, MouseListener {
// lots of code, including the two segments excerpted below
}
此代码段重载JPanel的的paintComponent使我的数据绘制:
// declare some variables
ArrayList<Double> PeakList = new ArrayList<Double>() // this ArrayList is populated by an extraneous process
visiblePoints = 5000
hstep = getWidth()/visiblePoints //=581/5000 by default, but will change when user resizes window
int numPeaks = PeakList.size();
// scale (y-coordinate) data relative to height of panel
pts = new double[visiblePoints]
for (int i = 0; i < pts.length-1; i++){pts[i]=//data vertical scaled to fill panel;}
// plot the 5000 time-series-data-points within the 581 pixels in x-axis
for (int i = 1; i < visiblePoints; i++) {
int x1 = (int) ((i - 1) * hstep);
int x2 = (int) (i * hstep);
int y1 = (int)pts[i - 1];
int y2 = (int)pts[i];
g2.drawLine(x1, y1, x2, y2);
}
// plot a rectangle for each of the local peaks
for(int m=0;m<=(numPeaks-1);m++){
if(i==(int)(PeakList.get(m)){
int currentVal = (int)pts[(int)(PeakList.get(m)];
g2.drawRect((int)(PeakList.get(m), currentVal, 6, 6);
}
}
这部分代码是用于处理鼠标右击:
public void mousePressed(MouseEvent e){
// check to see if right mouse button was clicked
boolean jones = (e.getModifiers()&InputEvent.BUTTON3_MASK)==InputEvent.BUTTON3_MASK;
if(jones==true){
// test the value returned as x-coordinate when user right-clicks (code always underestimates x-coordinate of local peaks by this test)
double ReverseHstep = visiblePoints/getWidth();
int getX_ConvertedTo_i = (int) (e.getX()*ReverseHstep);
System.out.println("getX_ConvertedTo_i is: "+getX_ConvertedTo_i);
// check to see if peaklist contains a value within the x-coordinates of the user-selected-rectangle
if(PeakList.contains((double)(e.getX()-3))
||PeakList.contains((double)(e.getX()-2))
||PeakList.contains((double)(e.getX()-1))
||PeakList.contains((double)(e.getX()))
||PeakList.contains((double)(e.getX()+1))
||PeakList.contains((double)(e.getX()+2))
||PeakList.contains((double)(e.getX()+3))
){
// handling code will go here, but for now it is a print test that never succeeds because x-coordinate is always underestimated
System.out.println("You just selected a peak!");
}
}
repaint();
}
我一直在测试这个,我通过右键单击获得的x坐标分别在相应的期望值的92.7%和93.8%之间PeakList ArrayList中的峰值。这说明问题可能是由于系统舍入误差。 – CodeMed
你绘制了多少个矩形?如果不是太多,你可能会使每个矩形成为一个单独的对象,让他们监听点击事件。那么它在哪里绘制就没有关系了。 – Jeremy
我有大约300万个数据点,其中可能有3500个本地峰值,每个峰值都需要自己的矩形。在任何给定时刻,JPanel中只绘制了5000个数据点,并且在该5000数据点窗口中可能有5到15个本地峰值,但面板底部有一个滚动条,允许用户滚动3个百万个数据点查看所有3500个峰值。 JPanel在用户使用滚动条时重新绘制。 – CodeMed