构建描述的LineChart需要花费15分钟
JavaFX,这对我的任务不起作用.
使用好的旧Swing和jFreeChart的类似实现需要1.5秒来构建图表.
但我还是想实现一个JavaFX.
这是我的代码:
public class FXMLController implements Initializable { @FXML private Label statusbar; @FXML public LineChart lineChart; @FXML public Button connect; @FXML public MenuItem options; @FXML public NumberAxis xAxis; @FXML NumberAxis yAxis; @FXML private void connect(ActionEvent event) { } public static FileChooser fileChooser = new FileChooser(); public static String path; public static XYChart.Series<Integer,Integer> dataSeries = new XYChart.Series<Integer,Integer>(); public static int y = 0; public static XYChart.Data<Integer,Integer> data; @FXML private void open(ActionEvent event) { fileChooser.setTitle("Open Resource File"); fileChooser.getExtensionFilters().addAll( new ExtensionFilter("Text Files","*.txt"),new ExtensionFilter("Image Files","*.png","*.jpg","*.gif"),new ExtensionFilter("Audio Files","*.wav","*.mp3","*.aac"),new ExtensionFilter("All Files","*.*")); File selectedFile = fileChooser.showOpenDialog(new Stage()); if (selectedFile != null) { path = selectedFile.getAbsolutePath(); System.out.println(path); try { ReadingFromFile.readFile(path); } catch (IOException ex) { Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE,null,ex); } } } @FXML private void close(ActionEvent event) { } @FXML private void getconnect(ActionEvent event) { } @Override public void initialize(URL url,ResourceBundle rb) { xAxis.setLabel("Tick"); xAxis.setTickUnit(100); yAxis.setLabel("Signal"); xAxis.setForceZeroInRange(false); lineChart.setLegendVisible(false); lineChart.setCreateSymbols(false); lineChart.setAnimated(false); lineChart.getData().add(dataSeries); } }
并从文件中读取:
public class ReadingFromFile extends FXMLController { public static String s = null; public static String[] str; public static int parseInt; public static void readFile(String filename) throws IOException { BufferedReader br = new BufferedReader(new FileReader(filename)); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); sb.append(System.lineSeparator()); line = br.readLine(); System.out.println(line); try { str = line.split(" "); for (int i = 0; i < str.length; i = i + 2) { s = str[i + 1] + str[i]; parseInt = Integer.parseInt(s,16); javafx.application.Platform.runLater(new Runnable() { @Override public void run() { data = new XYChart.Data<Integer,Integer>(y,parseInt); //data.setNode(new HoveredThresholdNode(0,second,"")); dataSeries.getData().add(data); y++; } }); } } catch (java.lang.NullPointerException ex) { System.out.println("тут ноль!!!"); } } } finally { br.close(); } } }
解决方法
我遇到了类似的问题,每隔几秒就会给一次LineChart增加100,000点.我们使用
Ramer–Douglas–Peucker algorithm解决了它,这减少了线路中的点数而没有用户注意到.我在
JTS topology suite根据LGPL许可证找到了现成的实施方案.
这是我的测试代码.
public class ChartUpdate extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { NumberAxis xAxis = new NumberAxis(0,50_000,5000); xAxis.setAutoRanging(false); NumberAxis yAxis = new NumberAxis(-1,1,25); yAxis.setAutoRanging(false); LineChart<Number,Number> graph = new LineChart<>(xAxis,yAxis); graph.setAnimated(false); graph.setCreateSymbols(false); graph.setLegendVisible(false); Series<Number,Number> series = new Series<>(); stage.setScene(new Scene(graph)); GeometryFactory gf = new GeometryFactory(); long t0 = System.nanoTime(); Coordinate[] coordinates = new Coordinate[100_000]; for (int i = 0; i < coordinates.length; i++) { coordinates[i] = new Coordinate(i,Math.sin(Math.toRadians(i / 100))); } Geometry geom = new LineString(new CoordinateArraySequence(coordinates),gf); Geometry simplified = DouglasPeuckerSimplifier.simplify(geom,0.00001); List<Data<Number,Number>> update = new ArrayList<Data<Number,Number>>(); for (Coordinate each : simplified.getCoordinates()) { update.add(new Data<>(each.x,each.y)); } long t1 = System.nanoTime(); System.out.println(String.format("Reduces points from %d to %d in %.1f ms",coordinates.length,update.size(),(t1 - t0) / 1e6)); ObservableList<Data<Number,Number>> list = FXCollections.observableArrayList(update); series.setData(list); graph.getData().add(series); stage.show(); } }