All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.gsi.chart.plugins.CrosshairIndicator Maven / Gradle / Ivy

/*
 * Copyright (c) 2016 European Organisation for Nuclear Research (CERN), All Rights Reserved.
 */

package de.gsi.chart.plugins;

import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.scene.text.Text;

import de.gsi.chart.axes.Axis;
import de.gsi.dataset.spi.utils.Tuple;

/**
 * Horizontal and vertical {@link Line} drawn on the plot area, crossing at the mouse cursor location, together with a
 * {@link Text} displaying the cursor coordinates in data units.
 * 

* CSS style class names: {@value #STYLE_CLASS_PATH} and {@value #STYLE_CLASS_LABEL} * * @author Grzegorz Kruk */ public class CrosshairIndicator extends AbstractDataFormattingPlugin { public static final String STYLE_CLASS_PATH = "chart-crosshair-path"; public static final String STYLE_CLASS_LABEL = "chart-crosshair-label"; private static final int LABEL_X_OFFSET = 15; private static final int LABEL_Y_OFFSET = 5; protected final Path crosshairPath = new Path(); protected final Text coordinatesLabel = new Text(); /** * Creates a new instance of CrosshairIndicator class. */ public CrosshairIndicator() { crosshairPath.getStyleClass().add(CrosshairIndicator.STYLE_CLASS_PATH); crosshairPath.setManaged(false); crosshairPath.setId("crosshairIndicator-Path"); coordinatesLabel.getStyleClass().add(CrosshairIndicator.STYLE_CLASS_LABEL); coordinatesLabel.setManaged(false); coordinatesLabel.setId("crosshairIndicator-Label"); final EventHandler mouseMoveHandler = (final MouseEvent event) -> { if (!isMouseEventWithinCanvas(event)) { getChartChildren().remove(crosshairPath); getChartChildren().remove(coordinatesLabel); return; } final Bounds plotAreaBounds = getChart().getBoundsInLocal(); updatePath(event, plotAreaBounds); updateLabel(event, plotAreaBounds); if (!getChartChildren().contains(crosshairPath)) { getChartChildren().addAll(crosshairPath, coordinatesLabel); } }; registerInputEventHandler(MouseEvent.ANY, mouseMoveHandler); } private String formatLabelText(final Point2D displayPointInPlotArea) { final Axis yAxis = getChart().getFirstAxis(Orientation.VERTICAL); if (yAxis == null) { return getChart() + " - " + "no y-axis present to translate point " + displayPointInPlotArea; } Tuple tuple = toDataPoint(yAxis, displayPointInPlotArea); if (tuple == null) { return "unknown coordinate"; } return formatData(getChart(), tuple); } private void updateLabel(final MouseEvent event, final Bounds plotAreaBounds) { coordinatesLabel.setText(formatLabelText(getLocationInPlotArea(event))); final double width = coordinatesLabel.prefWidth(-1); final double height = coordinatesLabel.prefHeight(width); double xLocation = event.getX() + CrosshairIndicator.LABEL_X_OFFSET; double yLocation = event.getY() + CrosshairIndicator.LABEL_Y_OFFSET; if (xLocation + width > plotAreaBounds.getMaxX()) { xLocation = event.getX() - CrosshairIndicator.LABEL_X_OFFSET - width; } if (yLocation + height > plotAreaBounds.getMaxY()) { yLocation = event.getY() - CrosshairIndicator.LABEL_Y_OFFSET - height; } coordinatesLabel.resizeRelocate(xLocation, yLocation, width, height); } private void updatePath(final MouseEvent event, final Bounds plotAreaBounds) { final ObservableList path = crosshairPath.getElements(); path.clear(); path.add(new MoveTo(plotAreaBounds.getMinX() + 1, event.getY())); path.add(new LineTo(plotAreaBounds.getMaxX(), event.getY())); path.add(new MoveTo(event.getX(), plotAreaBounds.getMinY() + 1)); path.add(new LineTo(event.getX(), plotAreaBounds.getMaxY())); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy