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

lecho.lib.hellocharts.gesture.ChartZoomer Maven / Gradle / Ivy

There is a newer version: 1.5.8
Show newest version
package lecho.lib.hellocharts.gesture;

import android.content.Context;
import android.graphics.PointF;
import android.view.MotionEvent;

import lecho.lib.hellocharts.computator.ChartComputator;
import lecho.lib.hellocharts.model.Viewport;

/**
 * Encapsulates zooming functionality.
 */
public class ChartZoomer {
    public static final float ZOOM_AMOUNT = 0.25f;
    private ZoomerCompat zoomer;
    private ZoomType zoomType;
    private PointF zoomFocalPoint = new PointF();// Used for double tap zoom
    private PointF viewportFocus = new PointF();
    private Viewport scrollerStartViewport = new Viewport(); // Used only for zooms and flings

    public ChartZoomer(Context context, ZoomType zoomType) {
        zoomer = new ZoomerCompat(context);
        this.zoomType = zoomType;
    }

    public boolean startZoom(MotionEvent e, ChartComputator computator) {
        zoomer.forceFinished(true);
        scrollerStartViewport.set(computator.getCurrentViewport());
        if (!computator.rawPixelsToDataPoint(e.getX(), e.getY(), zoomFocalPoint)) {
            // Focus point is not within content area.
            return false;
        }
        zoomer.startZoom(ZOOM_AMOUNT);
        return true;
    }

    public boolean computeZoom(ChartComputator computator) {
        if (zoomer.computeZoom()) {
            // Performs the zoom since a zoom is in progress.
            final float newWidth = (1.0f - zoomer.getCurrZoom()) * scrollerStartViewport.width();
            final float newHeight = (1.0f - zoomer.getCurrZoom()) * scrollerStartViewport.height();
            final float pointWithinViewportX = (zoomFocalPoint.x - scrollerStartViewport.left)
                    / scrollerStartViewport.width();
            final float pointWithinViewportY = (zoomFocalPoint.y - scrollerStartViewport.bottom)
                    / scrollerStartViewport.height();

            float left = zoomFocalPoint.x - newWidth * pointWithinViewportX;
            float top = zoomFocalPoint.y + newHeight * (1 - pointWithinViewportY);
            float right = zoomFocalPoint.x + newWidth * (1 - pointWithinViewportX);
            float bottom = zoomFocalPoint.y - newHeight * pointWithinViewportY;
            setCurrentViewport(computator, left, top, right, bottom);
            return true;
        }
        return false;
    }

    public boolean scale(ChartComputator computator, float focusX, float focusY, float scale) {
        /**
         * Smaller viewport means bigger zoom so for zoomIn scale should have value <1, for zoomOout >1
         */
        final float newWidth = scale * computator.getCurrentViewport().width();
        final float newHeight = scale * computator.getCurrentViewport().height();
        if (!computator.rawPixelsToDataPoint(focusX, focusY, viewportFocus)) {
            // Focus point is not within content area.
            return false;
        }

        float left = viewportFocus.x - (focusX - computator.getContentRectMinusAllMargins().left)
                * (newWidth / computator.getContentRectMinusAllMargins().width());
        float top = viewportFocus.y + (focusY - computator.getContentRectMinusAllMargins().top)
                * (newHeight / computator.getContentRectMinusAllMargins().height());
        float right = left + newWidth;
        float bottom = top - newHeight;
        setCurrentViewport(computator, left, top, right, bottom);
        return true;
    }

    private void setCurrentViewport(ChartComputator computator, float left, float top, float right, float bottom) {
        Viewport currentViewport = computator.getCurrentViewport();
        if (ZoomType.HORIZONTAL_AND_VERTICAL == zoomType) {
            computator.setCurrentViewport(left, top, right, bottom);
        } else if (ZoomType.HORIZONTAL == zoomType) {
            computator.setCurrentViewport(left, currentViewport.top, right, currentViewport.bottom);
        } else if (ZoomType.VERTICAL == zoomType) {
            computator.setCurrentViewport(currentViewport.left, top, currentViewport.right, bottom);
        }
    }

    public ZoomType getZoomType() {
        return zoomType;
    }

    public void setZoomType(ZoomType zoomType) {
        this.zoomType = zoomType;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy