Skip to content

Commit

Permalink
Zoomer: base zoom calculations on pixels
Browse files Browse the repository at this point in the history
Previously the zoomer would perform the scroll-zoom and panning
calculations in data coordinates. This is identical to pixel coordinates
for linear axes, but for e.g. log axes this leads to strange behaviour
since it can result in negative data values.

This changes the Pan and pan and scroll behaviour, the rectangle zoom
was naturally always using screen coordinates anyway, so this should
also be more consistent.
  • Loading branch information
wirew0rm committed Aug 17, 2023
1 parent d1304a1 commit a6d1596
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
35 changes: 24 additions & 11 deletions chartfx-chart/src/main/java/io/fair_acc/chartfx/plugins/Zoomer.java
Original file line number Diff line number Diff line change
Expand Up @@ -859,15 +859,19 @@ private void panChart(final Chart chart, final Point2D mouseLocation) {

final Side side = axis.getSide();

final double prevData = axis.getValueForDisplay(side.isHorizontal() ? oldMouseX : oldMouseY);
final double newData = axis.getValueForDisplay(side.isHorizontal() ? newMouseX : newMouseY);
final double offset = prevData - newData;

final boolean allowsShift = side.isHorizontal() ? getAxisMode().allowsX() : getAxisMode().allowsY();
if (!hasBoundedRange(axis) && allowsShift) {
final double offset = (side.isHorizontal() ? oldMouseX : oldMouseY) - (side.isHorizontal() ? newMouseX : newMouseY);
axis.setAutoRanging(false);
// shift bounds
axis.set(axis.getMin() + offset, axis.getMax() + offset);
final double newMin = axis.getValueForDisplay(0 + offset);
final double newMax = axis.getValueForDisplay(axis.getLength() + offset);
if (side.isHorizontal()) {
axis.set(newMin, newMax);
} else {
axis.set(newMax, newMin);
}
axis.updateCachedTransforms();
}
}
previousMouseLocation = mouseLocation;
Expand Down Expand Up @@ -948,6 +952,7 @@ private void performZoom(Entry<Axis, ZoomState> zoomStateEntry, final boolean is
if (!hasBoundedRange(axis)) {
// only update if this axis is not bound to another (e.g. auto-range) managed axis)
axis.set(zoomState.zoomRangeMin, zoomState.zoomRangeMax);
axis.updateCachedTransforms();
}
}

Expand Down Expand Up @@ -1155,14 +1160,22 @@ private static void zoomOnAxis(final Axis axis, final ScrollEvent event) {
final boolean isHorizontal = axis.getSide().isHorizontal();

final double mousePos = isHorizontal ? event.getX() : event.getY();
final double posOnAxis = axis.getValueForDisplay(mousePos);
final double max = axis.getMax();
final double min = axis.getMin();
final double max = axis.getLength();
final double scaling = isZoomIn ? 0.9 : 1 / 0.9;
final double diffHalf1 = scaling * Math.abs(posOnAxis - min);
final double diffHalf2 = scaling * Math.abs(max - posOnAxis);
final double minDisplay;
final double maxDisplay;
if (isHorizontal) {
minDisplay = (1 - scaling) * mousePos;
maxDisplay = mousePos + scaling * (max - mousePos);
} else {
maxDisplay = (1 - scaling) * mousePos;
minDisplay = mousePos + scaling * (max - mousePos);
}
final double newMin = axis.getValueForDisplay(minDisplay);
final double newMax = axis.getValueForDisplay(maxDisplay);

axis.set(posOnAxis - diffHalf1, posOnAxis + diffHalf2);
axis.set(newMin, newMax);
axis.updateCachedTransforms();

axis.forceRedraw();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ public Node getChartPanel(final Stage primaryStage) {
// yAxis.setLogarithmBase(2);

final XYChart chart = new XYChart(xAxis, yAxis);
final Zoomer zoomer = new Zoomer();
zoomer.setPannerEnabled(false); // not recommended (ie. Axes do not support complex numbers, e.g. 'log(-1)')
chart.getPlugins().add(zoomer); // zoom around
chart.getPlugins().add(new Zoomer()); // zoom around
chart.getPlugins().add(new EditAxis()); // manually modify axis

root.getChildren().add(chart);
Expand Down

0 comments on commit a6d1596

Please sign in to comment.