qlik-oss/sn-scatter-plot

View on GitHub
src/view-handler/zoom.js

Summary

Maintainability
A
0 mins
Test Coverage
B
88%
import { eventToComponentPoint } from '../utils/event-utils';

const ZOOM_SCALE = 2 ** (1 / 2);

function transform(scale, start, end, factor) {
  const range = end - start;
  const value = start + range * scale;
  const newStart = value - range * scale * factor;
  const newEnd = newStart + range * factor;
  return [newStart, newEnd];
}

export default function zoom({ e, chart, componentSize, viewHandler, pinchZoomFactor, buttonZoomDirection, models }) {
  const { scale, maxScale, minScale, checkScale } = viewHandler.getMeta();
  const { xAxisMin, xAxisMax, yAxisMin, yAxisMax } = viewHandler.getDataView();
  let zoomFactor;
  let fixedPoint;
  let p;
  if (buttonZoomDirection) {
    zoomFactor = buttonZoomDirection === 'out' ? ZOOM_SCALE : 1 / ZOOM_SCALE;
    fixedPoint = { normX: 0.5, normY: 0.5 };
  } else {
    zoomFactor = pinchZoomFactor || (e.deltaY > 0 ? ZOOM_SCALE : 1 / ZOOM_SCALE);
    p = eventToComponentPoint(e, chart, componentSize);
    const { width, height } = componentSize;
    fixedPoint = { normX: p.x / width, normY: p.y / height };
  }
  const newScale = zoomFactor * scale;

  if (newScale > maxScale || newScale < minScale) {
    return;
  }

  if (newScale < scale && newScale < checkScale) {
    const { chartModel } = models;
    // Do not zoom in further if all bubbles in the same position
    const dataHandler = chartModel.query.getDataHandler();
    if (!dataHandler.getMeta().isBinnedData && chartModel.query.areSameVisiblePoints()) return;
  }

  const [xMin, xMax] = transform(fixedPoint.normX, xAxisMin, xAxisMax, zoomFactor);
  const [yMax, yMin] = transform(fixedPoint.normY, yAxisMax, yAxisMin, zoomFactor);
  const viewScale = Math.abs(xAxisMax - xAxisMin) / Math.abs(xMax - xMin);
  viewHandler.setDataView({
    xAxisMin: xMin,
    xAxisMax: xMax,
    yAxisMin: yMin,
    yAxisMax: yMax,
    deltaX: p ? (1 - viewScale) * p.x : 0,
    deltaY: p ? (1 - viewScale) * p.y : 0,
    scale: viewScale || 1,
  });
}