4 Replies Latest reply: Nov 7, 2012 4:47 AM by 935521 RSS

    How to draw arrows?

    935521
      This code plots a simple XYLine Chart
      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.chart.CategoryAxis;
      import javafx.scene.chart.LineChart;
      import javafx.scene.chart.NumberAxis;
      import javafx.scene.chart.XYChart;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;
      
      public class XyChart extends Application {
      
          @Override
          public void start(Stage stage) {
             stage.setTitle("Line plot");
              
             final CategoryAxis xAxis = new CategoryAxis();
             final NumberAxis yAxis = new NumberAxis(1, 21,0.1);
             
             yAxis.setTickUnit(1);
             yAxis.setPrefWidth(35);
             yAxis.setMinorTickCount(10);
                 
             yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis){
                  @Override
              public String toString(Number object){
                      String label;
                      label = String.format("%7.2f", object.floatValue());
                      return label;
              }
          });
      final LineChart<String, Number>lineChart = new LineChart<String, Number>(xAxis, yAxis);
      
             lineChart.setCreateSymbols(false);
             lineChart.setAlternativeRowFillVisible(false);
             lineChart.setLegendVisible(false);
                     
             XYChart.Series series1 = new XYChart.Series();
              
              series1.getData().add(new XYChart.Data("Jan", 1));
              series1.getData().add(new XYChart.Data("Feb", 4));
              series1.getData().add(new XYChart.Data("Mar", 2.5));
              series1.getData().add(new XYChart.Data("Apr", 5));
              series1.getData().add(new XYChart.Data("May", 6));
              series1.getData().add(new XYChart.Data("Jun", 8));
              series1.getData().add(new XYChart.Data("Jul", 12));
              series1.getData().add(new XYChart.Data("Aug", 8));
              series1.getData().add(new XYChart.Data("Sep", 11));
              series1.getData().add(new XYChart.Data("Oct", 13));
              series1.getData().add(new XYChart.Data("Nov", 10));
              series1.getData().add(new XYChart.Data("Dec", 20));
       
              BorderPane pane = new BorderPane();
              pane.setCenter(lineChart);          
              Scene scene = new Scene(pane, 800, 600);
              lineChart.setAnimated(false);
              lineChart.getData().addAll(series1);       
               
              stage.setScene(scene);
              stage.show();
          }
      
          public static void main(String[] args) {
              launch(args);
          }   
      }
      I would like to draw arrows on the chart by left mouse click pressed and moved,such as this example

      [http://s8.postimage.org/5xgu0j6kl/A02480.png]

      how to do this?

      Thanks!

      Edited by: 932518 on 6-nov-2012 4.32
        • 1. Re: How to draw arrows?
          shakir.gusaroff
          Hi. You can use a path to draw lines or you can use a canvas.
          import javafx.application.Application;
          import javafx.event.EventHandler;
          import javafx.scene.Group;
          import javafx.scene.Scene;
          import javafx.scene.chart.CategoryAxis;
          import javafx.scene.chart.LineChart;
          import javafx.scene.chart.NumberAxis;
          import javafx.scene.chart.XYChart;
          import javafx.scene.control.Label;
          import javafx.scene.input.MouseEvent;
          import javafx.scene.layout.BorderPane;
          import javafx.scene.paint.Color;
          import javafx.scene.shape.LineTo;
          import javafx.scene.shape.MoveTo;
          import javafx.scene.shape.Path;
          import javafx.stage.Stage;
          
          public class XyChart extends Application {
          
              Path path;
          
              public static void main(String[] args) {
                  launch(args);
              }
          
              @Override
              public void start(Stage stage) {
          
                  final CategoryAxis xAxis = new CategoryAxis();
                  final NumberAxis yAxis = new NumberAxis(1, 21, 0.1);
                  yAxis.setTickUnit(1);
                  yAxis.setPrefWidth(35);
                  yAxis.setMinorTickCount(10);
                  yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
                      @Override
                      public String toString(Number object) {
                          String label;
                          label = String.format("%7.2f", object.floatValue());
                          return label;
                      }
                  });
                  final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
          
                  lineChart.setCreateSymbols(false);
                  lineChart.setAlternativeRowFillVisible(false);
                  lineChart.setLegendVisible(false);
          
                  XYChart.Series series1 = new XYChart.Series();
          
                  series1.getData().add(new XYChart.Data("Jan", 1));
                  series1.getData().add(new XYChart.Data("Feb", 4));
                  series1.getData().add(new XYChart.Data("Mar", 2.5));
                  series1.getData().add(new XYChart.Data("Apr", 5));
                  series1.getData().add(new XYChart.Data("May", 6));
                  series1.getData().add(new XYChart.Data("Jun", 8));
                  series1.getData().add(new XYChart.Data("Jul", 12));
                  series1.getData().add(new XYChart.Data("Aug", 8));
                  series1.getData().add(new XYChart.Data("Sep", 11));
                  series1.getData().add(new XYChart.Data("Oct", 13));
                  series1.getData().add(new XYChart.Data("Nov", 10));
                  series1.getData().add(new XYChart.Data("Dec", 20));
          
                  BorderPane pane = new BorderPane();
                  pane.setCenter(lineChart);
                  Scene scene = new Scene(pane, 800, 600);
                  lineChart.setAnimated(false);
                  lineChart.getData().addAll(series1);
          
                  stage.setScene(scene);
          
                  path = new Path();
                  path.setStrokeWidth(1);
                  path.setStroke(Color.BLACK);
          
                  scene.setOnMouseDragged(mHandler);
                  scene.setOnMousePressed(mHandler);
                  pane.getChildren().add(path);
                  stage.setScene(scene);
                  stage.show();
              }
              EventHandler<MouseEvent> mHandler = new EventHandler<MouseEvent>() {
                  @Override
                  public void handle(MouseEvent me) {
                      if (me.getEventType() == MouseEvent.MOUSE_PRESSED) {
                          path.getElements().add(new MoveTo(me.getX(), me.getY()));
                      } else if (me.getEventType() == MouseEvent.MOUSE_DRAGGED) {
                          path.getElements().add(new LineTo(me.getX(), me.getY()));
                      }
          
                  }
              };
          }
          • 2. Re: How to draw arrows?
            935521
            Hi Shakir,

            is it possibile to draw arrows on chart? Your solution works good but it is a freehand draw.

            Thanks!
            • 3. Re: How to draw arrows?
              shakir.gusaroff
              Hi. It is possible to draw arrows on a chart. Please try the modified example:
               import javafx.application.Application;
              import javafx.event.EventHandler;
              import javafx.scene.Group;
              import javafx.scene.Scene;
              import javafx.scene.chart.CategoryAxis;
              import javafx.scene.chart.LineChart;
              import javafx.scene.chart.NumberAxis;
              import javafx.scene.chart.XYChart;
              import javafx.scene.control.Label;
              import javafx.scene.input.MouseEvent;
              import javafx.scene.layout.BorderPane;
              import javafx.scene.paint.Color;
              import javafx.scene.shape.LineTo;
              import javafx.scene.shape.MoveTo;
              import javafx.scene.shape.Path;
              import javafx.scene.shape.Polygon;
              import javafx.stage.Stage;
              
              public class XyChart extends Application {
                   Path path;
                   BorderPane pane = new BorderPane();
                  double startx = 0;
                  double starty = 0;
                  double endx = 0;
                  double endy = 0;
                  
              
                  public static void main(String[] args) {
                      launch(args);
                  }
              
                  @Override
                  public void start(Stage stage) {
              
                      final CategoryAxis xAxis = new CategoryAxis();
                      final NumberAxis yAxis = new NumberAxis(1, 21, 0.1);
                      yAxis.setTickUnit(1);
                      yAxis.setPrefWidth(35);
                      yAxis.setMinorTickCount(10);
                      yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
                          @Override
                          public String toString(Number object) {
                              String label;
                              label = String.format("%7.2f", object.floatValue());
                              return label;
                          }
                      });
                      final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);
              
                      lineChart.setCreateSymbols(false);
                      lineChart.setAlternativeRowFillVisible(false);
                      lineChart.setLegendVisible(false);
              
                      XYChart.Series series1 = new XYChart.Series();
              
                      series1.getData().add(new XYChart.Data("Jan", 1));
                      series1.getData().add(new XYChart.Data("Feb", 4));
                      series1.getData().add(new XYChart.Data("Mar", 2.5));
                      series1.getData().add(new XYChart.Data("Apr", 5));
                      series1.getData().add(new XYChart.Data("May", 6));
                      series1.getData().add(new XYChart.Data("Jun", 8));
                      series1.getData().add(new XYChart.Data("Jul", 12));
                      series1.getData().add(new XYChart.Data("Aug", 8));
                      series1.getData().add(new XYChart.Data("Sep", 11));
                      series1.getData().add(new XYChart.Data("Oct", 13));
                      series1.getData().add(new XYChart.Data("Nov", 10));
                      series1.getData().add(new XYChart.Data("Dec", 20));
              
                     
                      pane.setCenter(lineChart);
                      Scene scene = new Scene(pane, 800, 600);
                      lineChart.setAnimated(false);
                      lineChart.getData().addAll(series1);
              
                    
              
                       path = new Path();
                        path.setStrokeWidth(1);
                      path.setStroke(Color.BLACK);
              
                      scene.setOnMouseReleased(mHandler);
                      scene.setOnMousePressed(mHandler);
                      pane.getChildren().add(path);
                      stage.setScene(scene);
                      stage.show();
                  }
                  EventHandler<MouseEvent> mHandler = new EventHandler<MouseEvent>() {
                      @Override
                      public void handle(MouseEvent me) {
              
              
                          if (me.getEventType() == MouseEvent.MOUSE_PRESSED) {
                              startx = me.getX();
                              starty = me.getY();
                              path.getElements().add(new MoveTo(startx, starty));
              
              
                          } else if (me.getEventType() == MouseEvent.MOUSE_RELEASED) {
                              endx = me.getX();
                              endy = me.getY();
                              path.getElements().add(new LineTo(endx, endy));
              
                              Polygon arrow = new Polygon();
                              arrow.getPoints().addAll(new Double[]{
                                          0.0, 5.0,
                                          -5.0, -5.0,
                                          5.0, -5.0});
              
                              double angle = Math.atan2(endy - starty, endx - startx) * 180 / 3.14;
              
                              arrow.setRotate((angle - 90));
              
                              arrow.setTranslateX(startx);
                              arrow.setTranslateY(starty);
              
                              arrow.setTranslateX(endx);
                              arrow.setTranslateY(endy);
              
                              pane.getChildren().add(arrow);
              
                          }
              
                      }
                  };
              }
              • 4. Re: How to draw arrows?
                935521
                Your code is perfect, thank you very much!