The Line plotted by the following code can be compressed or expanded by left mouse click and drag on X and / or Y axis, as well as plots a crosshair on the chart.
It all works perfectly, but if I only change from
yAxis.setSide(Side.LEFT);
to
yAxis.setSide(Side.RIGHT);
there are no more events on X and Y axis and no crosshair plot.
Can anybody help to fix this code? Thanks all!
import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Node;
import javafx.scene.chart.LineChart;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineBuilder;
public class Rescaling extends Application {
Path path;
BorderPane pane;
Rectangle rect;
Line LH;
Line LV;
XYChart.Series series1 = new XYChart.Series();
SimpleDoubleProperty rectinitX = new SimpleDoubleProperty();
SimpleDoubleProperty rectinitY = 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);
yAxis.setSide(Side.LEFT);
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<>(xAxis, yAxis);
lineChart.setCreateSymbols(false);
lineChart.setAlternativeRowFillVisible(false);
lineChart.setAnimated(true);
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));
series1.getData().add(new XYChart.Data(11, 0.530123));
series1.getData().add(new XYChart.Data(12, 0.531035));
pane = new BorderPane();
pane.setCenter(lineChart);
Scene scene = new Scene(pane, 800, 600);
lineChart.getData().addAll(series1);
stage.setScene(scene);
path = new Path();
path.setStrokeWidth(5);
path.setStroke(Color.RED);
scene.setOnMouseClicked(mouseHandler);
scene.setOnMouseDragged(mouseHandler);
scene.setOnMouseEntered(mouseHandler);
scene.setOnMouseExited(mouseHandler);
scene.setOnMouseMoved(mouseHandler);
scene.setOnMousePressed(mouseHandler);
scene.setOnMouseReleased(mouseHandler);
rect = new Rectangle();
rect.setFill(Color.web("yellow", 0.3));
rect.setStroke(Color.MAGENTA);
rect.setStrokeDashOffset(50);
rect.widthProperty().bind(rectX.subtract(rectinitX));
rect.heightProperty().bind(rectY.subtract(rectinitY));
pane.getChildren().add(rect);
LH=LineBuilder.create()
.startX(0)
.startY(0)
.endX(10)
.endY(.535)
.strokeWidth(1)
.stroke(Color.BLACK)
.build();
pane.getChildren().add(LH);
LV=LineBuilder.create()
.startX(0)
.startY(0)
.endX(10)
.endY(.535)
.strokeWidth(1)
.stroke(Color.BLACK)
.build();
pane.getChildren().add(LV);
stage.show();
}
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
boolean XScaling=false;
boolean YScaling=false;
if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) {
rect.setX(mouseEvent.getX());
rect.setY(mouseEvent.getY());
rectinitX.set(mouseEvent.getX());
rectinitY.set(mouseEvent.getY());
LH.setStartX(0);
LH.setStartY(0);
LH.setEndX(0);
LH.setEndY(0);
LV.setStartX(0);
LV.setStartY(0);
LV.setEndX(0);
LV.setEndY(0);
}
else if (mouseEvent.getEventType() == MouseEvent.MOUSE_RELEASED) {
rectX.set(mouseEvent.getX());
rectY.set(mouseEvent.getY());
// Hide the rectangle
rectX.set(0);
rectY.set(0);
}
else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED ){
LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter();
NumberAxis yAxis = (NumberAxis) lineChart.getYAxis();
NumberAxis xAxis = (NumberAxis) lineChart.getXAxis();
double Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound());
double newXlower=xAxis.getLowerBound(), newXupper=xAxis.getUpperBound();
double newYlower=yAxis.getLowerBound(), newYupper=yAxis.getUpperBound();
double xAxisShift = getSceneShift(xAxis);
double yAxisShift = getSceneShift(yAxis);
double yAxisStep=yAxis.getHeight()/(yAxis.getUpperBound()-yAxis.getLowerBound());
double CurrentPrice=yAxis.getUpperBound()-((mouseEvent.getY()-yAxisShift)/yAxisStep);
double Delta=0.3;
if(mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED && mouseEvent.getX()>xAxisShift && mouseEvent.getY()<yAxisShift+yAxis.getHeight() && (XScaling==false || YScaling==false)){
//==================================================== X-Axis Moving ==================================
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 );
//===================================================== Y-Axis Moving ====================================
if(rectinitY.get() < mouseEvent.getY()){
newYlower=yAxis.getLowerBound()+Delta/1000;
newYupper=yAxis.getUpperBound()+Delta/1000;
}
else if(rectinitY.get() > mouseEvent.getY()){
newYlower=yAxis.getLowerBound()-Delta/1000;
newYupper=yAxis.getUpperBound()-Delta/1000;
}
yAxis.setLowerBound(newYlower);
yAxis.setUpperBound(newYupper);
}
//----------------------------- Re-Scale the X-Axis when dragging below it ---------------------------------
else if(mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED && mouseEvent.getY()>yAxisShift+yAxis.getHeight() ){
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 );
}
//--------------------------------- Re-Scale the Y-Axis when dragging to the left of it --------------------------
else if(mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED && mouseEvent.getX()<xAxisShift){
if(rectinitY.get() < mouseEvent.getY()){
newYlower=yAxis.getLowerBound()-Delta/1000;
newYupper=yAxis.getUpperBound()+Delta/1000;
}
else if(rectinitY.get() > mouseEvent.getY()){
newYlower=yAxis.getLowerBound()+Delta/1000;
newYupper=yAxis.getUpperBound()-Delta/1000;
}
yAxis.setLowerBound(newYlower);
yAxis.setUpperBound(newYupper);
}
rectinitX.set(mouseEvent.getX());
rectinitY.set(mouseEvent.getY());
if(mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED && mouseEvent.getY()>yAxisShift && mouseEvent.getY()<yAxisShift+yAxis.getHeight() && mouseEvent.getX()>xAxisShift && mouseEvent.getX()<xAxisShift+xAxis.getWidth()){
LH.setStartX(xAxisShift);
LH.setStartY(mouseEvent.getY());
LH.setEndX(xAxisShift+xAxis.getWidth());
LH.setEndY(mouseEvent.getY());
LV.setStartX(mouseEvent.getX());
LV.setStartY(yAxisShift);
LV.setEndX(mouseEvent.getX());
LV.setEndY(yAxisShift+yAxis.getHeight());
double XX=((mouseEvent.getX() - xAxisShift) / Tgap) + xAxis.getLowerBound();
double YY=CurrentPrice;
series1.setName(String.format("%.2g%n",XX) + ", " + String.format("%.4g%n",YY));
}
}
}
};
private static double getSceneShift(Node node) {
double shift = 0;
do {
shift += node.getLayoutX();
node = node.getParent();
} while (node != null);
return shift;
}
public static void main(String[] args) {
launch(args);
}
}