繁体   English   中英

用户在Java中的时间序列数据中选择的标记

[英]User-selected marker in time series data in Java

我的代码在默认为581像素宽的面板中绘制了5000点的时间序列数据,但是当用户调整窗口大小时,该宽度会改变。 我的代码还绘制了几个矩形标记,每个标记都标识了同一空间中的局部最大值/峰值。

我需要使用户能够右键单击任何一个矩形峰标记,以便用户可以手动删除任何错误的峰。 问题是,当用户右键单击峰标记时,我的代码报告的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();
    }

我建议您为要单击的每件事创建对象(在本例中为Rectangles )。 这是一个简化的示例,说明如何使绘制的内容可点击。 要避免的关键是mouseClicked方法,该方法在鼠标在矩形内单击时才会显示对话框。

棘手的一点是,如果不在其上绘制另一个矩形,就无法弄清楚如何用颜色填充矩形。 我会把那个留给你;-)

public class Canvas extends JPanel implements MouseListener{
    private Rectangle rect = new Rectangle(100,100);

    public Canvas(){
        this.addMouseListener(this);
        rect.setSize(100, 100);
    }

    @Override
    public void paintComponent(Graphics g){
        g.setClip(rect);
        g.setColor(Color.RED);
        g.fillRect(0, 0, 100, 100);
    }

    @Override
    public void mouseClicked(MouseEvent e){
        if(rect.contains(e.getPoint())){
            JOptionPane.showConfirmDialog(this, "Click!");
        }
    }

    // The rest of the MouseListener methods have been cut out

    public static void main(String[] a){
        JFrame frame = new JFrame("Canvas Thingy");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(0, 0, 300, 300);
        frame.add(new Canvas());
        frame.setVisible(true);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM