2012-07-17 2 views
2

XY 선 차트 있음 왼쪽 마우스 클릭으로 X 축과 Y 축 모두에 대해 데이터 시각화를 압축/확장하고, 누르고 계속 누르고 있으면 왼쪽/오른쪽 및 위/아래로 드래그합니다. 여기 JavaFX 2 데이터 차트 압축/확장

는 차트 예를

enter image description here

이며, 여기에 샘플 데이터

을 그릴 수있는 코드는
public class BaseXYChart extends Application { 

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

    final CategoryAxis xAxis = new CategoryAxis(); 
    final NumberAxis yAxis = new NumberAxis(1, 22, 0.5); 

    yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis){ 
     @Override 
    public String toString(Number object){ 
     return String.format("%7.2f", object); 
    } 
}); 
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", 1.5)); 
    series1.getData().add(new XYChart.Data("Mar", 2)); 
    series1.getData().add(new XYChart.Data("Apr", 2.5)); 
    series1.getData().add(new XYChart.Data("May", 3)); 
    series1.getData().add(new XYChart.Data("Jun", 4)); 
    series1.getData().add(new XYChart.Data("Jul", 6)); 
    series1.getData().add(new XYChart.Data("Aug", 9)); 
    series1.getData().add(new XYChart.Data("Sep", 12)); 
    series1.getData().add(new XYChart.Data("Oct", 15)); 
    series1.getData().add(new XYChart.Data("Nov", 20)); 
    series1.getData().add(new XYChart.Data("Dec", 22)); 

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

    stage.setScene(scene); 
    stage.show(); 
} 

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

어떻게 이러한 목표를 달성 할 수 있습니까? 어디에도 예제가 없습니다!

감사합니다.

사진을 마우스 왼쪽 클릭 후

Result after left mouse click, pressed and drag on Y Axis from top to bottom

결과를 추가, X 축이 왼쪽으로 압축 된 라인 데이터를 얻을 수 있도록해야 누르면 상하

같은 결과 처음부터 Y 축에 드래그/마우스 오른쪽 버튼으로 드래그

답변

3

내가 올바르게 질문을 이해한다면 아마도 다음과 같이 축의 클릭 및 드래그를 기반으로 차트 크기를 조정할 수 있습니다.

import javafx.application.Application; 
import javafx.collections.FXCollections; 
import javafx.event.EventHandler; 
import javafx.scene.*; 
import javafx.scene.chart.*; 
import javafx.scene.effect.DropShadow; 
import javafx.scene.effect.Effect; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 

public class DraggableAxisResizableChart extends Application { 
    private static final int UNDEFINED = -1; 
    public static void main(String[] args) { launch(args); } 
    @Override public void start(Stage stage) { 
    final NumberAxis xAxis = new NumberAxis(); 
    final NumberAxis yAxis = new NumberAxis(); 
    final LineChart<Number, Number> chart = new LineChart(
     xAxis, yAxis, 
     FXCollections.observableArrayList(
     new XYChart.Series("April", FXCollections.observableArrayList(
      new XYChart.Data(0, 4), new XYChart.Data(1, 10), new XYChart.Data(2, 18), new XYChart.Data(3, 15) 
     )) 
    )  
    ); 
    chart.setPrefSize(400, 300); 
    chart.setMaxSize(400, 300); 
    makeXAxisDraggable(xAxis, chart); 
    makeYAxisDraggable(yAxis, chart); 

    StackPane layout = new StackPane(); 
    layout.getChildren().add(chart); 
    stage.setScene(new Scene(layout, 800, 600)); 
    stage.show(); 
    } 

    private void makeXAxisDraggable(final NumberAxis xAxis, final LineChart<Number, Number> chart) { 
    final Delta d = new Delta(); 
    xAxis.setOnMouseDragged(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     if (d.x == UNDEFINED) { 
      d.x = event.getSceneX(); 
      d.y = event.getSceneY(); 
     } else { 
      chart.setMaxHeight(
      chart.getPrefHeight() * (
       (chart.getPrefHeight() + (event.getSceneY() - d.y) * 2)/chart.getPrefHeight() 
      ) 
     ); 
     } 
     } 
    }); 

    xAxis.setOnMouseReleased(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     d.x = UNDEFINED; d.y = UNDEFINED; 
     chart.setPrefSize(chart.getMaxWidth(), chart.getMaxHeight()); 
     } 
    }); 

    addMouseoverGlow(xAxis); 
    } 

    private void makeYAxisDraggable(final NumberAxis yAxis, final LineChart<Number, Number> chart) { 
    final Delta d = new Delta(); 
    yAxis.setOnMouseDragged(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     if (d.x == -1) { 
      d.x = event.getSceneX(); 
      d.y = event.getSceneY(); 
     } else { 
      chart.setMaxWidth(
      chart.getPrefWidth() * (
       (chart.getPrefWidth() - (event.getSceneX() - d.x) * 2)/chart.getPrefWidth() 
      ) 
     ); 
     } 
     } 
    }); 

    yAxis.setOnMouseReleased(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     d.x = UNDEFINED; d.y = UNDEFINED; 
     chart.setPrefSize(chart.getMaxWidth(), chart.getMaxHeight()); 
     } 
    }); 

    addMouseoverGlow(yAxis); 
    } 

    // create a glow feedback effect on a node when the mouse is hovered over it. 
    private void addMouseoverGlow(final Node n) { 
    final Effect glow = new DropShadow(10, Color.GOLDENROD); 
    n.setOnMouseEntered(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     n.setEffect(glow); 
     } 
    }); 
    n.setOnMouseExited(new EventHandler<MouseEvent>() { 
     @Override public void handle(MouseEvent event) { 
     n.setEffect(null); 
     } 
    }); 
    } 

    // records a relative point location. 
    class Delta { double x = UNDEFINED, y = UNDEFINED; } 
} 

대체 구현에서는 노드에서 눈금을 사용할 수 있습니다.

위의 구현은 그래프 크기가 ​​조정될 때 약간의 고스트 흔적을 남겨 둡니다. 따라서 예제가 유용하다고 판단되면 어떻게 든 고칠 수 있습니다.

+0

감사합니다 jewelsea, 당신의 작품은 좋지만 내가 올바르게 달성해야 할 것을 설명하지 않았다고 생각합니다 : 일단 데이터가 플롯되어 있다면 (데이터는 플롯되어 있음을 의미합니다), 왼쪽 마우스 클릭, 계속 누르고 왼쪽으로 드래그하십시오./X 축에서 차트가 동일한 800,600 차원을 유지하는 동안 선 자체가 확장/축소 (즉 확대)해야합니다. 장면이 치수로 변경되지 않으며 선만 변경됩니다. 그림을 더 명확하게하려고 노력할 것입니다. –

+0

생각 나는 뭔가를 놓쳤습니다 ;-) 나는 [range] (http://docs.oracle.com/javafx/2/api/)를 조사하는 것이 좋습니다. javafx/scene/chart/NumberAxis.html # setRange % 28java.lang.Object, % 20boolean % 29)를 설정합니다. 끌기 감지 논리는 제공된 예제와 유사해야하지만 차트 크기가 아닌 최대/최소 범위 값을 조정해야합니다. – jewelsea

+0

jewelsea에 감사드립니다. 귀하의 제안을 귀하의 제안대로 수정하려고 노력할 것입니다. –