以下のようなソースにより、チャートをドラッグで範囲指定して拡大、クリックして戻す、を実装しています。
実際はデータが多く、見づらくなるため拡大したいのですが、
これをX軸をCategoryAxisにした場合でも同様に拡大したいのです。
Y軸にだけ拡大を実装することはできるのですが、X軸がそのままなので密になっている部分をピンポイントで拡大して見ることができていません。
ドラッグで直接拡大できずとも、何かしらうまい具合の操作で拡大して密な部分を表示する方法があれば教えていただければと思います。
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Test6 extends Application {
@Override public void start(Stage stage) { final NumberAxis xAxis = new NumberAxis(); final NumberAxis yAxis = new NumberAxis(); xAxis.setLabel("X軸"); yAxis.setLabel("Y軸"); //creating the chart final LineChart<Double, Double> lineChart = new LineChart(xAxis, yAxis); lineChart.setLegendVisible(false); ObservableList<XYChart.Series<Double, Double>> lineData = getLineData(); lineChart.setData(lineData); StackPane chartContainer = new StackPane(); new ChartZoom(lineChart, chartContainer); Scene scene = new Scene(chartContainer, 600, 400); stage.setScene(scene); stage.show(); }
private ObservableList<XYChart.Series<Double, Double>> getLineData() {
Series<Double, Double> series1 = new Series<>();
Series<Double, Double> series2 = new Series<>();
for (int i = 0; i < 50; i++) { series1.getData().add(new XYChart.Data<Double, Double>(Math.random() * 2 - 1.4, Math.random() - .7)); series2.getData().add(new XYChart.Data<Double, Double>(Math.random() * 2 - .6, Math.random() - .3)); } ObservableList<XYChart.Series<Double, Double>> seriesList = FXCollections.observableArrayList(); seriesList.addAll(series1, series2); return seriesList; } public static void main(String[] args) { launch(args); }
}
class ChartZoom extends Rectangle {
private StackPane chartContainer; private LineChart lineChart; public ChartZoom(LineChart lineChart, StackPane chartContainer) { this.chartContainer = chartContainer; this.lineChart = lineChart; this.chartContainer.getChildren().add(lineChart); this.chartContainer.getChildren().add(this); initZoom(); setManaged(false); setFill(Color.LIGHTSEAGREEN.deriveColor(0, 1, 1, 0.5)); setUpZooming(); } //初期状態 private void initZoom() { NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); NumberAxis yAxis = (NumberAxis) lineChart.getYAxis(); xAxis.setAutoRanging(true); xAxis.setForceZeroInRange(false); yAxis.setAutoRanging(true); yAxis.setForceZeroInRange(false); } //押下、ドラッグ、離脱で座標を取得 private void setUpZooming() { final ObjectProperty<Point2D> mouseAnchor = new SimpleObjectProperty<>(); lineChart.setOnMousePressed((MouseEvent event) -> { setFill(Color.LIGHTSEAGREEN.deriveColor(0, 1, 1, 0.5)); mouseAnchor.set(new Point2D(event.getX(), event.getY())); setWidth(0); setHeight(0); }); lineChart.setOnMouseDragged((MouseEvent event) -> { double x = event.getX(); double y = event.getY(); setX(Math.min(x, mouseAnchor.get().getX())); setY(Math.min(y, mouseAnchor.get().getY())); setWidth(x - mouseAnchor.get().getX()); setHeight(y - mouseAnchor.get().getY()); }); lineChart.setOnMouseReleased((MouseEvent event) -> { if ((getWidth() > 0) && (getHeight() > 0)) { doZoom(); }else { initZoom(); } }); } //拡大範囲を設定 private void doZoom() { Point2D zoomTopLeft = new Point2D(getX(), getY()); Point2D zoomBottomRight = new Point2D(getX() + getWidth(), getY() + getHeight()); Point2D chartInScene = lineChart.localToScene(0, 0); NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); xAxis.setAutoRanging(false); Point2D xAxisInScene = xAxis.localToScene(0, 0); NumberAxis yAxis = (NumberAxis) lineChart.getYAxis(); yAxis.setAutoRanging(false); double xOffset = zoomTopLeft.getX() - xAxisInScene.getX() + chartInScene.getX(); double yOffset = zoomBottomRight.getY() - xAxisInScene.getY() + chartInScene.getY(); double xAxisScale = xAxis.getScale(); double yAxisScale = yAxis.getScale(); xAxis.setLowerBound(xAxis.getLowerBound() + xOffset / xAxisScale); xAxis.setUpperBound(xAxis.getLowerBound() + getWidth() / xAxisScale); yAxis.setLowerBound(yAxis.getLowerBound() + yOffset / yAxisScale); yAxis.setUpperBound(yAxis.getLowerBound() - getHeight() / yAxisScale); setWidth(0); setHeight(0); }
}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/02/14 03:32