JavaFx LineChart Mouse Location Zoom With ScrollEvent












1















I am currently trying to implement LineChart mouse location zoom with ScrollEvent. I managed to do something but my problem is zooming into wrong direction. When my mouse stands on left side of lineChart, my zoom goes to right side of lineChart (symmetrical). Here is my code;



import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class ChartZoom extends Application {

@Override
public void start(Stage stage) {

LineChart<Number, Number> chart = chart();
final NumberAxis axis = (NumberAxis) chart.getXAxis();
final double lowerX = axis.getLowerBound();
final double upperX = axis.getUpperBound();

chart.setOnScroll(new EventHandler<ScrollEvent>() {

@Override
public void handle(ScrollEvent event) {
final double minX = axis.getLowerBound();
final double maxX = axis.getUpperBound();
double threshold = minX + (maxX - minX) / 2d;
double x = event.getX();
double value = axis.getValueForDisplay(x).doubleValue();
double direction = event.getDeltaY();
if (direction > 0) {
if (maxX - minX <= 1) {
return;
}
if (value < threshold) {
axis.setLowerBound(minX + 1);
} else {
axis.setUpperBound(maxX - 1);
}
} else {
if (value < threshold) {
double nextBound = Math.max(lowerX, minX - 1);
axis.setLowerBound(nextBound);
} else {
double nextBound = Math.min(upperX, maxX + 1);
axis.setUpperBound(nextBound);
}
}

}
});

BorderPane borderPane = new BorderPane();
borderPane.setCenter(chart);
Scene scene = new Scene(borderPane, 800, 600);
stage.setScene(scene);
stage.show();
}

private LineChart<Number, Number> chart() {
XYChart.Series series = new LineChart.Series<>();
final String days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
NumberAxis xAxis = new NumberAxis(0, days.length - 1, 1);
xAxis.setAutoRanging(false);
xAxis.setTickLabelFormatter(new StringConverter<Number>() {

@Override
public String toString(Number t) {
int index = t.intValue();
return (index >= 0 && index < days.length) ? days[index] : null;
}

@Override
public Number fromString(String string) {
throw new UnsupportedOperationException("Not supported yet.");
}
});
NumberAxis yAxis = new NumberAxis();
final LineChart<Number, Number> sc = new LineChart<>(xAxis, yAxis);
sc.setCreateSymbols(false);
sc.setPrefSize(1200, 210);
series.setName("Line Chart Series");
sc.getData().add(series);
series.getData().add(new LineChart.Data(0, 23));
series.getData().add(new LineChart.Data(1, 57));
series.getData().add(new LineChart.Data(2, 54));
series.getData().add(new LineChart.Data(3, 44));
series.getData().add(new LineChart.Data(4, 14));
series.getData().add(new LineChart.Data(5, 35));
series.getData().add(new LineChart.Data(6, 65));
return sc;
}

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









share|improve this question



























    1















    I am currently trying to implement LineChart mouse location zoom with ScrollEvent. I managed to do something but my problem is zooming into wrong direction. When my mouse stands on left side of lineChart, my zoom goes to right side of lineChart (symmetrical). Here is my code;



    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.chart.XYChart;
    import javafx.scene.input.ScrollEvent;
    import javafx.scene.layout.BorderPane;
    import javafx.stage.Stage;
    import javafx.util.StringConverter;

    public class ChartZoom extends Application {

    @Override
    public void start(Stage stage) {

    LineChart<Number, Number> chart = chart();
    final NumberAxis axis = (NumberAxis) chart.getXAxis();
    final double lowerX = axis.getLowerBound();
    final double upperX = axis.getUpperBound();

    chart.setOnScroll(new EventHandler<ScrollEvent>() {

    @Override
    public void handle(ScrollEvent event) {
    final double minX = axis.getLowerBound();
    final double maxX = axis.getUpperBound();
    double threshold = minX + (maxX - minX) / 2d;
    double x = event.getX();
    double value = axis.getValueForDisplay(x).doubleValue();
    double direction = event.getDeltaY();
    if (direction > 0) {
    if (maxX - minX <= 1) {
    return;
    }
    if (value < threshold) {
    axis.setLowerBound(minX + 1);
    } else {
    axis.setUpperBound(maxX - 1);
    }
    } else {
    if (value < threshold) {
    double nextBound = Math.max(lowerX, minX - 1);
    axis.setLowerBound(nextBound);
    } else {
    double nextBound = Math.min(upperX, maxX + 1);
    axis.setUpperBound(nextBound);
    }
    }

    }
    });

    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(chart);
    Scene scene = new Scene(borderPane, 800, 600);
    stage.setScene(scene);
    stage.show();
    }

    private LineChart<Number, Number> chart() {
    XYChart.Series series = new LineChart.Series<>();
    final String days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
    NumberAxis xAxis = new NumberAxis(0, days.length - 1, 1);
    xAxis.setAutoRanging(false);
    xAxis.setTickLabelFormatter(new StringConverter<Number>() {

    @Override
    public String toString(Number t) {
    int index = t.intValue();
    return (index >= 0 && index < days.length) ? days[index] : null;
    }

    @Override
    public Number fromString(String string) {
    throw new UnsupportedOperationException("Not supported yet.");
    }
    });
    NumberAxis yAxis = new NumberAxis();
    final LineChart<Number, Number> sc = new LineChart<>(xAxis, yAxis);
    sc.setCreateSymbols(false);
    sc.setPrefSize(1200, 210);
    series.setName("Line Chart Series");
    sc.getData().add(series);
    series.getData().add(new LineChart.Data(0, 23));
    series.getData().add(new LineChart.Data(1, 57));
    series.getData().add(new LineChart.Data(2, 54));
    series.getData().add(new LineChart.Data(3, 44));
    series.getData().add(new LineChart.Data(4, 14));
    series.getData().add(new LineChart.Data(5, 35));
    series.getData().add(new LineChart.Data(6, 65));
    return sc;
    }

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









    share|improve this question

























      1












      1








      1








      I am currently trying to implement LineChart mouse location zoom with ScrollEvent. I managed to do something but my problem is zooming into wrong direction. When my mouse stands on left side of lineChart, my zoom goes to right side of lineChart (symmetrical). Here is my code;



      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.chart.LineChart;
      import javafx.scene.chart.NumberAxis;
      import javafx.scene.chart.XYChart;
      import javafx.scene.input.ScrollEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;
      import javafx.util.StringConverter;

      public class ChartZoom extends Application {

      @Override
      public void start(Stage stage) {

      LineChart<Number, Number> chart = chart();
      final NumberAxis axis = (NumberAxis) chart.getXAxis();
      final double lowerX = axis.getLowerBound();
      final double upperX = axis.getUpperBound();

      chart.setOnScroll(new EventHandler<ScrollEvent>() {

      @Override
      public void handle(ScrollEvent event) {
      final double minX = axis.getLowerBound();
      final double maxX = axis.getUpperBound();
      double threshold = minX + (maxX - minX) / 2d;
      double x = event.getX();
      double value = axis.getValueForDisplay(x).doubleValue();
      double direction = event.getDeltaY();
      if (direction > 0) {
      if (maxX - minX <= 1) {
      return;
      }
      if (value < threshold) {
      axis.setLowerBound(minX + 1);
      } else {
      axis.setUpperBound(maxX - 1);
      }
      } else {
      if (value < threshold) {
      double nextBound = Math.max(lowerX, minX - 1);
      axis.setLowerBound(nextBound);
      } else {
      double nextBound = Math.min(upperX, maxX + 1);
      axis.setUpperBound(nextBound);
      }
      }

      }
      });

      BorderPane borderPane = new BorderPane();
      borderPane.setCenter(chart);
      Scene scene = new Scene(borderPane, 800, 600);
      stage.setScene(scene);
      stage.show();
      }

      private LineChart<Number, Number> chart() {
      XYChart.Series series = new LineChart.Series<>();
      final String days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
      NumberAxis xAxis = new NumberAxis(0, days.length - 1, 1);
      xAxis.setAutoRanging(false);
      xAxis.setTickLabelFormatter(new StringConverter<Number>() {

      @Override
      public String toString(Number t) {
      int index = t.intValue();
      return (index >= 0 && index < days.length) ? days[index] : null;
      }

      @Override
      public Number fromString(String string) {
      throw new UnsupportedOperationException("Not supported yet.");
      }
      });
      NumberAxis yAxis = new NumberAxis();
      final LineChart<Number, Number> sc = new LineChart<>(xAxis, yAxis);
      sc.setCreateSymbols(false);
      sc.setPrefSize(1200, 210);
      series.setName("Line Chart Series");
      sc.getData().add(series);
      series.getData().add(new LineChart.Data(0, 23));
      series.getData().add(new LineChart.Data(1, 57));
      series.getData().add(new LineChart.Data(2, 54));
      series.getData().add(new LineChart.Data(3, 44));
      series.getData().add(new LineChart.Data(4, 14));
      series.getData().add(new LineChart.Data(5, 35));
      series.getData().add(new LineChart.Data(6, 65));
      return sc;
      }

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









      share|improve this question














      I am currently trying to implement LineChart mouse location zoom with ScrollEvent. I managed to do something but my problem is zooming into wrong direction. When my mouse stands on left side of lineChart, my zoom goes to right side of lineChart (symmetrical). Here is my code;



      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.scene.Scene;
      import javafx.scene.chart.LineChart;
      import javafx.scene.chart.NumberAxis;
      import javafx.scene.chart.XYChart;
      import javafx.scene.input.ScrollEvent;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;
      import javafx.util.StringConverter;

      public class ChartZoom extends Application {

      @Override
      public void start(Stage stage) {

      LineChart<Number, Number> chart = chart();
      final NumberAxis axis = (NumberAxis) chart.getXAxis();
      final double lowerX = axis.getLowerBound();
      final double upperX = axis.getUpperBound();

      chart.setOnScroll(new EventHandler<ScrollEvent>() {

      @Override
      public void handle(ScrollEvent event) {
      final double minX = axis.getLowerBound();
      final double maxX = axis.getUpperBound();
      double threshold = minX + (maxX - minX) / 2d;
      double x = event.getX();
      double value = axis.getValueForDisplay(x).doubleValue();
      double direction = event.getDeltaY();
      if (direction > 0) {
      if (maxX - minX <= 1) {
      return;
      }
      if (value < threshold) {
      axis.setLowerBound(minX + 1);
      } else {
      axis.setUpperBound(maxX - 1);
      }
      } else {
      if (value < threshold) {
      double nextBound = Math.max(lowerX, minX - 1);
      axis.setLowerBound(nextBound);
      } else {
      double nextBound = Math.min(upperX, maxX + 1);
      axis.setUpperBound(nextBound);
      }
      }

      }
      });

      BorderPane borderPane = new BorderPane();
      borderPane.setCenter(chart);
      Scene scene = new Scene(borderPane, 800, 600);
      stage.setScene(scene);
      stage.show();
      }

      private LineChart<Number, Number> chart() {
      XYChart.Series series = new LineChart.Series<>();
      final String days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
      NumberAxis xAxis = new NumberAxis(0, days.length - 1, 1);
      xAxis.setAutoRanging(false);
      xAxis.setTickLabelFormatter(new StringConverter<Number>() {

      @Override
      public String toString(Number t) {
      int index = t.intValue();
      return (index >= 0 && index < days.length) ? days[index] : null;
      }

      @Override
      public Number fromString(String string) {
      throw new UnsupportedOperationException("Not supported yet.");
      }
      });
      NumberAxis yAxis = new NumberAxis();
      final LineChart<Number, Number> sc = new LineChart<>(xAxis, yAxis);
      sc.setCreateSymbols(false);
      sc.setPrefSize(1200, 210);
      series.setName("Line Chart Series");
      sc.getData().add(series);
      series.getData().add(new LineChart.Data(0, 23));
      series.getData().add(new LineChart.Data(1, 57));
      series.getData().add(new LineChart.Data(2, 54));
      series.getData().add(new LineChart.Data(3, 44));
      series.getData().add(new LineChart.Data(4, 14));
      series.getData().add(new LineChart.Data(5, 35));
      series.getData().add(new LineChart.Data(6, 65));
      return sc;
      }

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






      javafx linechart zooming






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Feb 3 '16 at 15:20









      MertGMertG

      631112




      631112
























          2 Answers
          2






          active

          oldest

          votes


















          0














          Ok i just fixed it by changing 3rd if below



          if (direction > 0) {
          if (maxX - minX <= 1) {
          return;
          }
          if (value < threshold) { // if(value > threshold)
          axis.setLowerBound(minX + 1);
          } else {
          axis.setUpperBound(maxX - 1);
          }





          share|improve this answer































            0














            You can use jfxutils.



            To quickly implement a zoom function to you current LineChart use the ChartPaneManager. Remember that zooming functionality only works for LineChart<Number, Number>



            https://github.com/gillius/jfxutils/releases



                ChartPanManager panner = new ChartPanManager(lineChartPrices);
            //while presssing the left mouse button, you can drag to navigate
            panner.setMouseFilter(mouseEvent -> {
            if (mouseEvent.getButton() == MouseButton.PRIMARY) {//set your custom combination to trigger navigation
            // let it through
            } else {
            mouseEvent.consume();
            }
            });
            panner.start();

            //holding the right mouse button will draw a rectangle to zoom to desired location
            JFXChartUtil.setupZooming(lineChartPrices, mouseEvent -> {
            if (mouseEvent.getButton() != MouseButton.SECONDARY)//set your custom combination to trigger rectangle zooming
            mouseEvent.consume();
            });





            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35180914%2fjavafx-linechart-mouse-location-zoom-with-scrollevent%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              Ok i just fixed it by changing 3rd if below



              if (direction > 0) {
              if (maxX - minX <= 1) {
              return;
              }
              if (value < threshold) { // if(value > threshold)
              axis.setLowerBound(minX + 1);
              } else {
              axis.setUpperBound(maxX - 1);
              }





              share|improve this answer




























                0














                Ok i just fixed it by changing 3rd if below



                if (direction > 0) {
                if (maxX - minX <= 1) {
                return;
                }
                if (value < threshold) { // if(value > threshold)
                axis.setLowerBound(minX + 1);
                } else {
                axis.setUpperBound(maxX - 1);
                }





                share|improve this answer


























                  0












                  0








                  0







                  Ok i just fixed it by changing 3rd if below



                  if (direction > 0) {
                  if (maxX - minX <= 1) {
                  return;
                  }
                  if (value < threshold) { // if(value > threshold)
                  axis.setLowerBound(minX + 1);
                  } else {
                  axis.setUpperBound(maxX - 1);
                  }





                  share|improve this answer













                  Ok i just fixed it by changing 3rd if below



                  if (direction > 0) {
                  if (maxX - minX <= 1) {
                  return;
                  }
                  if (value < threshold) { // if(value > threshold)
                  axis.setLowerBound(minX + 1);
                  } else {
                  axis.setUpperBound(maxX - 1);
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Feb 4 '16 at 8:24









                  MertGMertG

                  631112




                  631112

























                      0














                      You can use jfxutils.



                      To quickly implement a zoom function to you current LineChart use the ChartPaneManager. Remember that zooming functionality only works for LineChart<Number, Number>



                      https://github.com/gillius/jfxutils/releases



                          ChartPanManager panner = new ChartPanManager(lineChartPrices);
                      //while presssing the left mouse button, you can drag to navigate
                      panner.setMouseFilter(mouseEvent -> {
                      if (mouseEvent.getButton() == MouseButton.PRIMARY) {//set your custom combination to trigger navigation
                      // let it through
                      } else {
                      mouseEvent.consume();
                      }
                      });
                      panner.start();

                      //holding the right mouse button will draw a rectangle to zoom to desired location
                      JFXChartUtil.setupZooming(lineChartPrices, mouseEvent -> {
                      if (mouseEvent.getButton() != MouseButton.SECONDARY)//set your custom combination to trigger rectangle zooming
                      mouseEvent.consume();
                      });





                      share|improve this answer




























                        0














                        You can use jfxutils.



                        To quickly implement a zoom function to you current LineChart use the ChartPaneManager. Remember that zooming functionality only works for LineChart<Number, Number>



                        https://github.com/gillius/jfxutils/releases



                            ChartPanManager panner = new ChartPanManager(lineChartPrices);
                        //while presssing the left mouse button, you can drag to navigate
                        panner.setMouseFilter(mouseEvent -> {
                        if (mouseEvent.getButton() == MouseButton.PRIMARY) {//set your custom combination to trigger navigation
                        // let it through
                        } else {
                        mouseEvent.consume();
                        }
                        });
                        panner.start();

                        //holding the right mouse button will draw a rectangle to zoom to desired location
                        JFXChartUtil.setupZooming(lineChartPrices, mouseEvent -> {
                        if (mouseEvent.getButton() != MouseButton.SECONDARY)//set your custom combination to trigger rectangle zooming
                        mouseEvent.consume();
                        });





                        share|improve this answer


























                          0












                          0








                          0







                          You can use jfxutils.



                          To quickly implement a zoom function to you current LineChart use the ChartPaneManager. Remember that zooming functionality only works for LineChart<Number, Number>



                          https://github.com/gillius/jfxutils/releases



                              ChartPanManager panner = new ChartPanManager(lineChartPrices);
                          //while presssing the left mouse button, you can drag to navigate
                          panner.setMouseFilter(mouseEvent -> {
                          if (mouseEvent.getButton() == MouseButton.PRIMARY) {//set your custom combination to trigger navigation
                          // let it through
                          } else {
                          mouseEvent.consume();
                          }
                          });
                          panner.start();

                          //holding the right mouse button will draw a rectangle to zoom to desired location
                          JFXChartUtil.setupZooming(lineChartPrices, mouseEvent -> {
                          if (mouseEvent.getButton() != MouseButton.SECONDARY)//set your custom combination to trigger rectangle zooming
                          mouseEvent.consume();
                          });





                          share|improve this answer













                          You can use jfxutils.



                          To quickly implement a zoom function to you current LineChart use the ChartPaneManager. Remember that zooming functionality only works for LineChart<Number, Number>



                          https://github.com/gillius/jfxutils/releases



                              ChartPanManager panner = new ChartPanManager(lineChartPrices);
                          //while presssing the left mouse button, you can drag to navigate
                          panner.setMouseFilter(mouseEvent -> {
                          if (mouseEvent.getButton() == MouseButton.PRIMARY) {//set your custom combination to trigger navigation
                          // let it through
                          } else {
                          mouseEvent.consume();
                          }
                          });
                          panner.start();

                          //holding the right mouse button will draw a rectangle to zoom to desired location
                          JFXChartUtil.setupZooming(lineChartPrices, mouseEvent -> {
                          if (mouseEvent.getButton() != MouseButton.SECONDARY)//set your custom combination to trigger rectangle zooming
                          mouseEvent.consume();
                          });






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Dec 30 '18 at 5:12









                          Wesos de QuesoWesos de Queso

                          511715




                          511715






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35180914%2fjavafx-linechart-mouse-location-zoom-with-scrollevent%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Monofisismo

                              Angular Downloading a file using contenturl with Basic Authentication

                              Olmecas