2012-09-24 8 views
2

이 코드는 LineChart 상단 창과 하단 창에서 막대 차트를 그립니다.JavaFX 2.x : 하위 창에서 세로선 확장

포인터로 왼쪽/오른쪽 X 이동을 플롯 한 수직선이 있습니다.

I는 첨부 된 그림이 작업을 수행하는 방법

enter image description here

같이, 하부에 subpane이 수직선을 연장 하시겠습니까?

감사합니다. 여기

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.collections.ObservableList; 
import javafx.event.EventHandler; 
import javafx.geometry.Orientation; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.chart.*; 
import javafx.scene.control.SplitPane; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Line; 
import javafx.scene.shape.LineBuilder; 
import javafx.stage.Stage; 

public class XyChartInSplitOnlyCursor extends Application { 
SplitPane    splitPane1 = null; 
BorderPane    pane1; 
BorderPane    pane2; 
Line     LV; 
XYChart.Series   series1 = new XYChart.Series(); 
XYChart.Series   series2 = new XYChart.Series(); 

@Override 
public void start(Stage stage) {  
stage.setTitle("Lines plot"); 

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

xAxis.setAnimated(false); 
xAxis.setScaleX(0); 
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> lineChart1 = new LineChart<Number, Number>(xAxis, yAxis); 

lineChart1.setCreateSymbols(false); 
lineChart1.setAlternativeRowFillVisible(false); 
lineChart1.setAnimated(false); 
lineChart1.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)); 

lineChart1.getData().addAll(series1);   

pane1 = new BorderPane(); 
pane1.setCenter(lineChart1); 

splitPane1 = new SplitPane();         
splitPane1.setOrientation(Orientation.VERTICAL); 
splitPane1.getItems().addAll(pane1); 
splitPane1.setDividerPosition(0, 1); 

final CategoryAxis xAxis2 = new CategoryAxis(); 
final NumberAxis yAxis2 = new NumberAxis(); 

yAxis2.setTickUnit(1); 
yAxis2.setPrefWidth(35); 
yAxis2.setMinorTickCount(10); 

yAxis2.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis2){ 
     @Override 
     public String toString(Number object){ 
      String label; 
      label = String.format("%7.2f", object.floatValue()); 
      return label; 
     } 
}); 

final BarChart<String, Number>BarChart = new BarChart<String, Number>(xAxis2, yAxis2); 

BarChart.setAlternativeRowFillVisible(false); 
BarChart.setLegendVisible(false); 
BarChart.setAnimated(false); 

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

series2.getData().add(new XYChart.Data("Jan", 1)); 
series2.getData().add(new XYChart.Data("Feb", 3)); 
series2.getData().add(new XYChart.Data("Mar", 1.5)); 
series2.getData().add(new XYChart.Data("Apr", 3)); 
series2.getData().add(new XYChart.Data("May", 4.5)); 
series2.getData().add(new XYChart.Data("Jun", 5)); 
series2.getData().add(new XYChart.Data("Jul", 4)); 
series2.getData().add(new XYChart.Data("Aug", 8)); 
series2.getData().add(new XYChart.Data("Sep", 16.5)); 
series2.getData().add(new XYChart.Data("Oct", 13.9)); 
series2.getData().add(new XYChart.Data("Nov", 17)); 
series2.getData().add(new XYChart.Data("Dec", 20)); 

BarChart.getData().addAll(series2); 

pane2 = new BorderPane(); 
pane2.setCenter(BarChart); 

Platform.runLater(new Runnable() { 
    @Override 
    public void run() { 
     double percSplit; 

     splitPane1.getItems().addAll(pane2); 

     ObservableList<SplitPane.Divider> splitDiv = splitPane1.getDividers(); 

     percSplit = 1/(double)(splitDiv.size()+1); 
     for (int i = 0; i< splitDiv.size(); i++) {       
      splitPane1.setDividerPosition(i, percSplit); 
      percSplit += 1/(double)(splitDiv.size()+1); 
      } 
    } 
}); 

Scene scene = new Scene(splitPane1, 800, 600); 
stage.setScene(scene);   

pane1.setOnMouseMoved(mouseHandler); 

LV=LineBuilder.create() 
     .startX(0) 
     .startY(0) 
     .endX(10) 
     .endY(.535) 
     .strokeWidth(1) 
     .stroke(Color.BLACK) 
     .build(); 
pane1.getChildren().add(LV); 

stage.show(); 
} 
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 

@Override 
public void handle(MouseEvent mouseEvent) { 
    if (mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
     LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane1.getCenter(); 

     NumberAxis yAxis = (NumberAxis) lineChart.getYAxis(); 
     NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 

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

     double xAxisShift = getSceneShift(xAxis); 
     double yAxisShift = getSceneShift(yAxis); 

     if(mouseEvent.getX()>xAxisShift && mouseEvent.getX()<xAxisShift+xAxis.getWidth()){ 

     LV.setStartX(mouseEvent.getX()); 
     LV.setStartY(yAxisShift); 
     LV.setEndX(mouseEvent.getX()); 
     LV.setEndY(yAxisShift+yAxis.getHeight()); 
     } 
    } 
} 
}; 
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); 
} 
} 

편집 코드입니다 : jewelsea 후 추가 사진 수정

enter image description here

답변

3

레이어를 그룹을 대신 분할 구획의 창에 줄을 추가 생성하지 마십시오 SplitPane의 선. 당신이 장면의 크기를 재조정하려면

Scene scene = new Scene(new Group(splitPane1, line), 800, 600); 

, 당신은 그룹 대신 StackPane를 사용하고이 장면을 채우기 위해 얻을 수있는 장면 높이로 줄 길이를 바인딩 할 수 있습니다.

다음은 StackPane을 사용하여 적용하고 크기 조정할 수있는 장면에서 선을 바인딩하는 예제입니다. 참고로 원래 게시 된 코드와 마찬가지로 코드가 명시 적으로 코딩되어 마우스가 상단 차트의 플롯 영역 안에있을 때만 선을 이동합니다.

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.collections.ObservableList; 
import javafx.event.EventHandler; 
import javafx.geometry.Orientation; 
import javafx.scene.*; 
import javafx.scene.chart.*; 
import javafx.scene.control.SplitPane; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.*; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Line; 
import javafx.scene.shape.LineBuilder; 
import javafx.stage.Stage; 

public class XyChartInSplitOnlyCursor extends Application { 
    SplitPane splitPane1 = null; 
    BorderPane pane1; 
    BorderPane pane2; 
    Line LV1, LV2; 
    XYChart.Series series1 = new XYChart.Series(); 
    XYChart.Series series2 = new XYChart.Series(); 

    @Override 
    public void start(Stage stage) { 
    stage.setTitle("Lines plot"); 

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

    xAxis.setAnimated(false); 
    xAxis.setScaleX(0); 
    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> lineChart1 = new LineChart<Number, Number>(xAxis, yAxis); 

    lineChart1.setCreateSymbols(false); 
    lineChart1.setAlternativeRowFillVisible(false); 
    lineChart1.setAnimated(false); 
    lineChart1.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)); 

    lineChart1.getData().addAll(series1); 

    pane1 = new BorderPane(); 
    pane1.setCenter(lineChart1); 

    splitPane1 = new SplitPane(); 
    splitPane1.setOrientation(Orientation.VERTICAL); 
    splitPane1.getItems().addAll(pane1); 
    splitPane1.setDividerPosition(0, 1); 

    final CategoryAxis xAxis2 = new CategoryAxis(); 
    final NumberAxis yAxis2 = new NumberAxis(); 

    yAxis2.setTickUnit(1); 
    yAxis2.setPrefWidth(35); 
    yAxis2.setMinorTickCount(10); 

    yAxis2.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis2) { 
     @Override 
     public String toString(Number object) { 
     String label; 
     label = String.format("%7.2f", object.floatValue()); 
     return label; 
     } 
    }); 

    final BarChart<String, Number> BarChart = new BarChart<String, Number>(xAxis2, yAxis2); 

    BarChart.setAlternativeRowFillVisible(false); 
    BarChart.setLegendVisible(false); 
    BarChart.setAnimated(false); 

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

    series2.getData().add(new XYChart.Data("Jan", 1)); 
    series2.getData().add(new XYChart.Data("Feb", 3)); 
    series2.getData().add(new XYChart.Data("Mar", 1.5)); 
    series2.getData().add(new XYChart.Data("Apr", 3)); 
    series2.getData().add(new XYChart.Data("May", 4.5)); 
    series2.getData().add(new XYChart.Data("Jun", 5)); 
    series2.getData().add(new XYChart.Data("Jul", 4)); 
    series2.getData().add(new XYChart.Data("Aug", 8)); 
    series2.getData().add(new XYChart.Data("Sep", 16.5)); 
    series2.getData().add(new XYChart.Data("Oct", 13.9)); 
    series2.getData().add(new XYChart.Data("Nov", 17)); 
    series2.getData().add(new XYChart.Data("Dec", 20)); 

    BarChart.getData().addAll(series2); 

    pane2 = new BorderPane(); 
    pane2.setCenter(BarChart); 

    Platform.runLater(new Runnable() { 
     @Override 
     public void run() { 
     double percSplit; 

     splitPane1.getItems().addAll(pane2); 

     ObservableList<SplitPane.Divider> splitDiv = splitPane1.getDividers(); 

     percSplit = 1/(double) (splitDiv.size() + 1); 
     for (int i = 0; i < splitDiv.size(); i++) { 
      splitPane1.setDividerPosition(i, percSplit); 
      percSplit += 1/(double) (splitDiv.size() + 1); 
     } 
     } 
    }); 

    LV1 = LineBuilder.create() 
      .strokeWidth(2) 
      .stroke(Color.FORESTGREEN) 
      .build(); 

    StackPane stack = new StackPane(); 
    Pane glassPane = new Pane(); 
    glassPane.getChildren().add(LV1); 
    glassPane.minWidthProperty().bind(splitPane1.widthProperty()); 
    glassPane.minHeightProperty().bind(splitPane1.heightProperty()); 
    glassPane.setMouseTransparent(true); 
    stack.getChildren().addAll(splitPane1, glassPane); 
    Scene scene = new Scene(stack, 800, 600); 
    LV1.endYProperty().bind(scene.heightProperty()); 
    stage.setScene(scene); 
    pane1.setOnMouseMoved(mouseHandler); 

    stage.show(); 
    } 

    EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 
    @Override public void handle(MouseEvent mouseEvent) { 
     XYChart<Number, Number> chart1 = (XYChart<Number, Number>) pane1.getCenter(); 
     plotLine(chart1, LV1, mouseEvent.getX() + 1); 
    } 
    }; 

    private void plotLine(XYChart<Number, Number> chart, Line line, double x) { 
    Axis xAxis = chart.getXAxis(), yAxis = chart.getYAxis(); 
    final double min = getSceneShift(xAxis); 
    final double max = min + xAxis.getWidth(); 
    boolean setCrosshair = false; 
    if (x > min && x < min + xAxis.getWidth()) { 
     LV1.setStartX(x); LV1.setEndX(x); 
     setCrosshair = true; 
    } else if (x <= min){ 
     LV1.setStartX(min); LV1.setEndX(min); 
    } else if (x >= max){ 
     LV1.setStartX(max); LV1.setEndX(max); 
    } 
    if (setCrosshair) { 
     chart.setCursor(Cursor.CROSSHAIR); 
    } else { 
     chart.setCursor(Cursor.DEFAULT); 
    } 
    } 

    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); 
    } 
} 

Sample program output

+0

안녕 jewelsea, 나는 당신의 제안 장면 장면 = 새로운 장면 (새 그룹 (splitPane1, LV), 800, 600) 후 사진과 함께 내 질문에 업데이트 한 ; 그러나 예상대로 결과를 얻지 못했습니다. 내가 뭔가를 놓치고, 또는 대안으로 바인딩을 사용하는 방법이 있습니까? 그렇다면 어떻게해야합니까? –

+0

그룹 만 사용하려면 추가 작업을 통해 그래프를 두 그래프 위로 확장해야합니다. 어쨌든 원본 샘플이 크기 조정이 가능하기 때문에 StackPane + Bind를 사용하여 샘플을 제공하는 답을 업데이트했습니다. – jewelsea

+0

안녕하세요 jewelsea, 훌륭한 작품, 대단히 감사합니다! –