私のコードは、デフォルトでパネルの幅が581ピクセルですが、ユーザーがウィンドウのサイズを変更すると5000ポイントの時系列データをプロットします。私のコードはまた、同じ空間内の極大/極大をそれぞれが識別するいくつかの長方形のマーカーをプロットします。Javaの時系列データでユーザーが選択したマーカー
私はユーザーが任意の誤ったピークを手動で削除できるように、長方形ピークマーカのどれかを右クリックする必要があります。問題は、ユーザーがピークマーカを右クリックしたときに、私のコードが予想外のx座標を報告していることです。私はその理由が、581 xピクセルから5000データインデックスに変換する際の丸め誤差と関係している可能性があると考えます。しかし、私はその理由を確信していません。
ユーザーは、上記のピークマーカーの1つを右クリックして手動で選択できるソリューションをお勧めしますか?
以下のコードの関連するセクションを囲んでいます。私の実際のコードは、非常に長く、投稿するのが難しいです。しかし、以下の関連部分は、誰かが自分のアプローチの論理を見て、より効果的なアプローチを提案するのに十分なはずです。
質問でクラスを宣言するコードは次のとおりです。
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
私は約3百万のデータポイントを持っています。そこには、おそらくそれぞれが自分の矩形を必要とする3500のローカルピークがあります。任意の時点で、JPanelには5000個のデータポイントしかプロットされておらず、5,000個のデータポイントウィンドウに5〜15個のローカルピークが存在するかもしれませんが、パネルの下部にスクロールバーがあり、すべての3500のピークを表示するために100万データポイント。 JPanelは、ユーザがスクロールバーをutlizeしたときに再描画されます。 – CodeMed