當嘗試構建包含可更新的LineChart
或AreaChart
的應用程序時,我發現奇怪的行爲 - 可能是由於應用程序邏輯中的錯誤?x軸上的JavaFX LineChart/AreaChart排序值錯誤(CategoryAxis)
目標是當單擊按鈕「生成」時填入數據或更新圖表。用戶必須輸入圖表的開始時間和結束時間,此外還必須選擇一個時間間隔/天/周(通過使用RadioGroup
)。
創建初始圖表沒有任何問題。重新生成圖表也能正常工作,但只要數據點在前面的圖表中不存在即可。如果兩個圖表(舊的和更新的)都包含具有相同x值的數據點,則排序不再上升。
實施例:
執行與 開始日期:2013年1月9日 結束日期:2013年9月25日 間隔:周
在x軸上的值:
2013年9月1日/ 2013年9月8日/ 15.09.2013/22.09.2013
單擊「天數」RadioButton
重新生成圖表得出x軸上的以下值:
2013年9月1日/ 2013年8月9日/ 2013年9月15日/ 2013年9月22日/ 2013年2月9日/ 2013年3月9日/ 2013年4月9日/ ...
(值應該是2013年9月1日/ 2013年2月9日/ 2013年3月9日/ ...)
這已經在第一張圖顯示出,並在第二個圖表太所有值,在新圖表的開始進行排序(而不是按升序排列)
這裏的(initializeTimeline
方法的代碼僅用於測試目的(當然可以優化;))):
public class ChartDesignController implements Initializable {
@FXML
private AreaChart chartOne;
@FXML
private TextField startDate;
@FXML
private TextField endDate;
@FXML
private RadioButton radioHours;
@FXML
private RadioButton radioDays;
@FXML
private RadioButton radioWeeks;
@FXML
private ToggleGroup timeUnit;
@FXML
private Label msgBox;
@FXML
private void generateGraph(ActionEvent event) {
String timeUnit = getTimeUnit();
Series s = initializeTimeline(startDate.getText(), endDate.getText(), timeUnit);
chartOne.getData().setAll(s);
}
private String getTimeUnit() {
String timeUnitForQuery = "DD";
RadioButton selectedRadio = (RadioButton) timeUnit.getSelectedToggle();
if (selectedRadio == radioHours) {
//System.out.println("RadioHours was selected");
timeUnitForQuery = "HH24";
}
if (selectedRadio == radioDays) {
//System.out.println("RadioDays was selected");
timeUnitForQuery = "DD";
}
if (selectedRadio == radioWeeks) {
//System.out.println("RadioWeeks was selected");
timeUnitForQuery = "IW";
}
//System.out.println("Time unit changed");
return timeUnitForQuery;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
private Series initializeTimeline(String startTime, String endTime, String timeUnit) {
msgBox.setText("");
long delta;
int nrOfTicks = 0;
Data<String, Integer> dp;
Series s = new Series();
ArrayList<Data<String, Integer>> dataPoints = new ArrayList();
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
Date startDate = new Date();
Date endDate = new Date();
GregorianCalendar startTimeGC = new GregorianCalendar();
GregorianCalendar endTimeGC = new GregorianCalendar();
if (timeUnit.equalsIgnoreCase("HH24")) {
sdf = new SimpleDateFormat("dd.MM.yyyy HH");
}
try {
startDate = sdf.parse(startTime);
endDate = sdf.parse(endTime);
} catch (ParseException ex) {
msgBox.setText(ex.getMessage() + "\n" + "Format expected: " + sdf.toPattern());
}
startTimeGC.setTimeInMillis(startDate.getTime());
endTimeGC.setTimeInMillis(endDate.getTime());
delta = endTimeGC.getTimeInMillis() - startTimeGC.getTimeInMillis();
if (timeUnit.equalsIgnoreCase("HH24")) {
nrOfTicks = (int) (delta/1000/60/60) + 1;
} else if (timeUnit.equalsIgnoreCase("DD")) {
nrOfTicks = (int) (delta/1000/60/60/24) + 1;
} else if (timeUnit.equalsIgnoreCase("IW")) {
nrOfTicks = (int) (delta/1000/60/60/24/7) + 1;
}
for (int i = 0; i < nrOfTicks; i++) {
dp = new Data(sdf.format(startTimeGC.getTime()), 0);
dataPoints.add(dp);
if (timeUnit.equalsIgnoreCase("HH24")) {
startTimeGC.add(GregorianCalendar.HOUR_OF_DAY, 1);
} else if (timeUnit.equalsIgnoreCase("DD")) {
startTimeGC.add(GregorianCalendar.DAY_OF_MONTH, 1);
} else if (timeUnit.equalsIgnoreCase("IW")) {
startTimeGC.add(GregorianCalendar.WEEK_OF_YEAR, 1);;
}
}
dataPoints.sort(new DataComparator());
s.setData(FXCollections.observableList(dataPoints));
return s;
}
}
下面,DataComparator
它負責排序dataPoints
的字母順序根據其x值:
public class DataComparator implements Comparator<Data> {
@Override
public int compare(Data d1, Data d2) {
String d1Xval = (String) d1.getXValue();
String d2Xval = (String) d2.getXValue();
return d1Xval.compareTo(d2Xval);
}
}
當調試程序值在ArrayList
dataPoints
正確排序。
任何想法爲什麼價值排序不正確,然後在圖表X軸,以防他們已經出現在舊圖表?
將非常感謝幫助這個「問題」。
答案你有沒有發現這方面的任何解決方案? – AloneInTheDark