001/* ================================================ 002 * JFreeChart-FX : JavaFX extensions for JFreeChart 003 * ================================================ 004 * 005 * (C) Copyright 2017-2021, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: https://github.com/jfree/jfreechart-fx 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * -------------------- 028 * ScrollHandlerFX.java 029 * -------------------- 030 * (C) Copyright 2014-2021, by Object Refinery Limited and Contributors. 031 * 032 * Original Author: David Gilbert (for Object Refinery Limited); 033 * Contributor(s): -; 034 * 035 */ 036 037package org.jfree.chart.fx.interaction; 038 039import java.awt.geom.Point2D; 040import javafx.scene.input.ScrollEvent; 041import org.jfree.chart.ChartRenderingInfo; 042import org.jfree.chart.JFreeChart; 043import org.jfree.chart.fx.ChartCanvas; 044import org.jfree.chart.plot.PiePlot; 045import org.jfree.chart.plot.Plot; 046import org.jfree.chart.plot.PlotRenderingInfo; 047import org.jfree.chart.plot.Zoomable; 048 049/** 050 * Handles scroll events (mouse wheel etc) on a {@link ChartCanvas}. 051 */ 052public class ScrollHandlerFX extends AbstractMouseHandlerFX 053 implements MouseHandlerFX { 054 055 /** The zoom factor. */ 056 private double zoomFactor = 0.1; 057 058 /** 059 * Creates a new instance with the specified ID. 060 * 061 * @param id the handler ID ({@code null} not permitted). 062 */ 063 public ScrollHandlerFX(String id) { 064 super(id, false, false, false, false); 065 this.zoomFactor = 0.1; 066 }; 067 068 /** 069 * Returns the zoom factor. The default value is 0.10 (ten percent). 070 * 071 * @return The zoom factor. 072 */ 073 public double getZoomFactor() { 074 return this.zoomFactor; 075 } 076 077 /** 078 * Sets the zoom factor (a percentage amount by which the mouse wheel 079 * movement will change the chart size). 080 * 081 * @param zoomFactor the zoom factor. 082 */ 083 public void setZoomFactor(double zoomFactor) { 084 this.zoomFactor = zoomFactor; 085 } 086 087 @Override 088 public void handleScroll(ChartCanvas canvas, ScrollEvent e) { 089 JFreeChart chart = canvas.getChart(); 090 if (chart == null) { 091 return; 092 } 093 Plot plot = chart.getPlot(); 094 if (plot instanceof Zoomable) { 095 Zoomable zoomable = (Zoomable) plot; 096 handleZoomable(canvas, zoomable, e); 097 } 098 else if (plot instanceof PiePlot) { 099 PiePlot pp = (PiePlot) plot; 100 pp.handleMouseWheelRotation((int) e.getDeltaY()); 101 } 102 } 103 104 /** 105 * Handle the case where a plot implements the {@link Zoomable} interface. 106 * 107 * @param canvas the chart canvas. 108 * @param zoomable the zoomable plot. 109 * @param e the mouse wheel event. 110 */ 111 private void handleZoomable(ChartCanvas canvas, Zoomable zoomable, 112 ScrollEvent e) { 113 if (canvas.getChart() == null) { 114 return; 115 } 116 // don't zoom unless the mouse pointer is in the plot's data area 117 ChartRenderingInfo info = canvas.getRenderingInfo(); 118 PlotRenderingInfo pinfo = info.getPlotInfo(); 119 Point2D p = new Point2D.Double(e.getX(), e.getY()); 120 if (pinfo.getDataArea().contains(p)) { 121 Plot plot = (Plot) zoomable; 122 // do not notify while zooming each axis 123 boolean notifyState = plot.isNotify(); 124 plot.setNotify(false); 125 int clicks = (int) e.getDeltaY(); 126 double zf = 1.0 + this.zoomFactor; 127 if (clicks < 0) { 128 zf = 1.0 / zf; 129 } 130 if (canvas.isDomainZoomable()) { 131 zoomable.zoomDomainAxes(zf, pinfo, p, true); 132 } 133 if (canvas.isRangeZoomable()) { 134 zoomable.zoomRangeAxes(zf, pinfo, p, true); 135 } 136 plot.setNotify(notifyState); // this generates the change event too 137 } 138 } 139 140}