2012-10-29 15 views
6

Poniższy kod rysuje XYLineChart: lewym przyciskiem myszy i przeciągnij linię z rysunkiem można przetłumaczyć w lewo/prawo.JavaFX 2.x: Jak przenieść linie, siatki i X kleszcze razem?

import javafx.application.Application; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.event.EventHandler; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.stage.Stage; 
import javafx.scene.Scene; 
import javafx.scene.chart.LineChart; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.BorderPane; 
enter code here 


public class GridMove extends Application { 

    BorderPane pane; 
    XYChart.Series series1 = new XYChart.Series(); 
    SimpleDoubleProperty rectinitX = new SimpleDoubleProperty(); 
    SimpleDoubleProperty rectX = new SimpleDoubleProperty(); 
    SimpleDoubleProperty rectY = new SimpleDoubleProperty(); 

    @Override 
    public void start(Stage stage) { 

     final NumberAxis xAxis = new NumberAxis(1, 12, 1); 
     final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005); 

     xAxis.setAnimated(false); 
     yAxis.setAnimated(false); 

     yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 
      @Override 
      public String toString(Number object) { 
       return String.format("%7.5f", object); 
      } 
     }); 

     final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis); 

     lineChart.setCreateSymbols(false); 
     lineChart.setAlternativeRowFillVisible(false); 
     lineChart.setAnimated(false); 
     lineChart.setLegendVisible(false); 

     series1.getData().add(new XYChart.Data(1, 0.53185)); 
     series1.getData().add(new XYChart.Data(2, 0.532235)); 
     series1.getData().add(new XYChart.Data(3, 0.53234)); 
     series1.getData().add(new XYChart.Data(4, 0.538765)); 
     series1.getData().add(new XYChart.Data(5, 0.53442)); 
     series1.getData().add(new XYChart.Data(6, 0.534658)); 
     series1.getData().add(new XYChart.Data(7, 0.53023)); 
     series1.getData().add(new XYChart.Data(8, 0.53001)); 
     series1.getData().add(new XYChart.Data(9, 0.53589)); 
     series1.getData().add(new XYChart.Data(10, 0.53476)); 

     pane = new BorderPane(); 
     pane.setCenter(lineChart); 
     Scene scene = new Scene(pane, 800, 600); 
     lineChart.getData().addAll(series1); 

     stage.setScene(scene); 

     scene.setOnMouseClicked(mouseHandler); 
     scene.setOnMouseDragged(mouseHandler); 
     scene.setOnMouseEntered(mouseHandler); 
     scene.setOnMouseExited(mouseHandler); 
     scene.setOnMouseMoved(mouseHandler); 
     scene.setOnMousePressed(mouseHandler); 
     scene.setOnMouseReleased(mouseHandler); 
     stage.show(); 
    } 
    EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 

      if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) { 
       rectinitX.set(mouseEvent.getX()); 
      } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
       LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter(); 
       NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 

       double Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound()); 
       double newXlower = xAxis.getLowerBound(), newXupper = xAxis.getUpperBound(); 
       double Delta = 0.3; 

       if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) { 
        if (rectinitX.get() < mouseEvent.getX()) { 
         newXlower = xAxis.getLowerBound() - Delta; 
         newXupper = xAxis.getUpperBound() - Delta; 
        } else if (rectinitX.get() > mouseEvent.getX()) { 
         newXlower = xAxis.getLowerBound() + Delta; 
         newXupper = xAxis.getUpperBound() + Delta; 
        } 
        xAxis.setLowerBound(newXlower); 
        xAxis.setUpperBound(newXupper); 
       } 
       rectinitX.set(mouseEvent.getX()); 
      } 
     } 
    }; 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Moje pytania są

1) Teraz przesuwając linię w lewo/prawo, siatki i X Kleszcze nie rusza: tak, jak tłumaczyć linia, siatki i X Ticks razem?

2) Czy jest to możliwe w JavaFx 2?

Dzięki

Edytuj Nikt nie chce pomóc?

Edit 2: instrukcje importu dodany

Edycja 3: ulepszenia Kodeksu, teraz siatka i kolejka przesuwa się razem. Pozostaje tylko przesuniecie tyknięć osi X wraz z linią i siatką, a pionowe linie siatki nie zawierają wartości z poza linii

import java.util.Set; 
import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.collections.ObservableList; 
import javafx.event.EventHandler; 
import javafx.scene.chart.Axis; 
import javafx.scene.chart.NumberAxis; 
import javafx.scene.chart.XYChart; 
import javafx.scene.chart.XYChart.Series; 
import javafx.stage.Stage; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.chart.LineChart; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.shape.LineTo; 
import javafx.scene.shape.MoveTo; 
import javafx.scene.shape.Path; 

public class GridMove extends Application { 

BorderPane pane; 

XYChart.Series series1 = new XYChart.Series(); 

SimpleDoubleProperty rectinitX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectY = new SimpleDoubleProperty(); 
LineChart<Number, Number> lineChart; 

@Override 
public void start(Stage stage) { 

    final NumberAxis xAxis = new NumberAxis(1, 12, 1); 
    final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005); 

    xAxis.setAnimated(false); 
    yAxis.setAnimated(false); 

    yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 
     @Override 
     public String toString(Number object) { 
      return String.format("%7.5f", object); 
     } 
    }); 

    lineChart = new LineChart<Number, Number>(xAxis, yAxis); 

    lineChart.setCreateSymbols(false); 
    lineChart.setAlternativeRowFillVisible(false); 
    lineChart.setAnimated(false); 
    lineChart.setLegendVisible(false); 

    series1.getData().add(new XYChart.Data(1, 0.53185)); 
    series1.getData().add(new XYChart.Data(2, 0.532235)); 
    series1.getData().add(new XYChart.Data(3, 0.53234)); 
    series1.getData().add(new XYChart.Data(4, 0.538765)); 
    series1.getData().add(new XYChart.Data(5, 0.53442)); 
    series1.getData().add(new XYChart.Data(6, 0.534658)); 
    series1.getData().add(new XYChart.Data(7, 0.53023)); 
    series1.getData().add(new XYChart.Data(8, 0.53001)); 
    series1.getData().add(new XYChart.Data(9, 0.53589)); 
    series1.getData().add(new XYChart.Data(10, 0.53476)); 

    pane = new BorderPane(); 
    pane.setCenter(lineChart); 
    Scene scene = new Scene(pane, 800, 600); 
    lineChart.getData().addAll(series1);    

    stage.setScene(scene); 

    scene.setOnMouseClicked(mouseHandler); 
    scene.setOnMouseDragged(mouseHandler); 
    scene.setOnMouseEntered(mouseHandler); 
    scene.setOnMouseExited(mouseHandler); 
    scene.setOnMouseMoved(mouseHandler); 
    scene.setOnMousePressed(mouseHandler); 
    scene.setOnMouseReleased(mouseHandler); 
    stage.show();  
} 
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent mouseEvent) { 

      if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) { 
      rectinitX.set(mouseEvent.getX()); 
     } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
      LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter(); 
      NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 

      double newXlower = xAxis.getLowerBound(), newXupper = xAxis.getUpperBound(); 
      double Delta = 0.3; 

      if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) { 
       if (rectinitX.get() < mouseEvent.getX()) { 
        Delta *= -1;      
       } 
       newXlower = xAxis.getLowerBound() + Delta; 
       newXupper = xAxis.getUpperBound() + Delta; 

       xAxis.setLowerBound(newXlower); 
       xAxis.setUpperBound(newXupper); 

       DoubleProperty p1 = xAxis.scaleXProperty(); 
       DoubleProperty p2 = xAxis.translateXProperty(); 

       double horizontalValueRange = xAxis.getUpperBound() - xAxis.getLowerBound(); 
       double horizontalWidthPixels = xAxis.getWidth(); 
       //pixels per unit 
       double xScale = horizontalWidthPixels/horizontalValueRange; 

       Set<Node> nodes = lineChart.lookupAll(".chart-vertical-grid-lines"); 
       for (Node n: nodes) { 
        Path p = (Path) n; 
        double currLayoutX = p.getLayoutX(); 
        p.setLayoutX(currLayoutX + (Delta*-1) * xScale); 
       }      
       double lox = xAxis.getLayoutX();          
      } 
      rectinitX.set(mouseEvent.getX()); 
     } 
    } 
}; 
public static void main(String[] args) { 
    launch(args); 
} 
} 

Każda pomoc bardzo ceniona!

+0

Co konkretnie próbujesz osiągnąć? Kiedy to skompiluję (przy okazji, proszę dołączyć importowanie następnym razem, Eclipse/Netbeans są sprytni, ale nie tak inteligentni) i uruchomcie go Widzę wykres poruszający się ze znacznikami * pozostając * z wykreślonymi punktami. To ma sens. Czy chcesz przetłumaczyć wykres (zmienić wszystkie wartości punktowe) lub czy chcesz przenieść wykres? Zdecydowanie poruszasz nim tak, jak jest. –

+0

Cześć Daniel: ten kod zmienia wartości kleszcza, podczas gdy siatka i znaczniki pozostają w bezruchu. Co więcej, ponieważ zakresy osi X w wartościach int od 1 do 10, nie powinienem mieć dziesiętnych podczas przesuwania w lewo/w prawo na wykresie liniowym –

+0

Kilka rzeczy: po uruchomieniu tyknięcia pozostają statyczne, ale zmieniają liczbę w celu odzwierciedlenia na co patrzysz (prawidłowe zachowanie). Po drugie, jeśli obawiasz się wartości kleszczy, musisz ustawić ją za pomocą całej wartości. W tej chwili używasz zdarzenia myszy (podwójne), które ustawia je na podwójne. Musisz wykonać pewne obliczenia, aby "zatrzasnąć" je przez zestawy (1), ale nie powinno to być zbyt trudne. Jeśli interesuje Cię przewijanie wykresu za pomocą kleszczy, będziesz musiał zajrzeć głębiej, to nie wydaje się być rozwiązaniem "na półce". –

Odpowiedz

0

To raczej komentarz, ale w jakiś sposób jestem zbyt nowy, aby komentować.

Podejdę do tego poprzez osadzenie wykresu w ScrollPane z niewidocznymi paskami przewijania i ustawię przezroczystość osi Y na wykresie na 0. Jeśli nie jest możliwe załadowanie wszystkich danych wykresu do pamięci, musisz zarządzać pobieranymi danymi w zdarzeniach przewijania itp.

Dodatkowo możesz użyć niezależnej funkcji NumberAxis dla swojej osi Y. Musisz skalować propped i pozycjonować ręcznie.

Powiązane problemy