/**
   * Compute a transformation matrix that pass from graph units (user space) to pixel units (device
   * space) so that the whole graph is visible.
   *
   * @param g2 The Swing graphics.
   */
  protected void autoFitView(Graphics2D g2) {
    double sx, sy;
    double tx, ty;
    double padXgu = getPaddingXgu() * 2;
    double padYgu = getPaddingYgu() * 2;
    double padXpx = getPaddingXpx() * 2;
    double padYpx = getPaddingYpx() * 2;

    sx = (metrics.viewport[2] - padXpx) / (metrics.size.data[0] + padXgu); // Ratio
    // along
    // X
    sy = (metrics.viewport[3] - padYpx) / (metrics.size.data[1] + padYgu); // Ratio
    // along
    // Y
    tx = metrics.lo.x + (metrics.size.data[0] / 2); // Centre of graph in X
    ty = metrics.lo.y + (metrics.size.data[1] / 2); // Centre of graph in Y

    if (sx <= 0) {
      sx =
          (metrics.viewport[2] - Math.min(metrics.viewport[2] - 1, padXpx))
              / (metrics.size.data[0] + padXgu);
    }

    if (sy <= 0) {
      sy =
          (metrics.viewport[3] - Math.min(metrics.viewport[3] - 1, padYpx))
              / (metrics.size.data[1] + padYgu);
    }

    if (sx > sy) // The least ratio.
    sx = sy;
    else sy = sx;

    g2.translate(metrics.viewport[2] / 2, metrics.viewport[3] / 2);
    if (rotation != 0) g2.rotate(rotation / (180 / Math.PI));
    g2.scale(sx, -sy);
    g2.translate(-tx, -ty);

    Tx = g2.getTransform();
    xT = new AffineTransform(Tx);
    try {
      xT.invert();
    } catch (NoninvertibleTransformException e) {
      logger.warning("Cannot inverse gu2px matrix.");
    }

    zoom = 1;

    center.set(tx, ty, 0);
    metrics.setRatioPx2Gu(sx);
    metrics.loVisible.copy(metrics.lo);
    metrics.hiVisible.copy(metrics.hi);
  }
  /**
   * Enable or disable automatic adjustment of the view to see the entire graph.
   *
   * @param on If true, automatic adjustment is enabled.
   */
  public void setAutoFitView(boolean on) {
    if (autoFit && (!on)) {
      // We go from autoFit to user view, ensure the current centre is at
      // the
      // middle of the graph, and the zoom is at one.

      zoom = 1;
      center.set(
          metrics.lo.x + (metrics.size.data[0] / 2), metrics.lo.y + (metrics.size.data[1] / 2), 0);
    }

    autoFit = on;
  }
 /*
  * (non-Javadoc)
  *
  * @see org.graphstream.ui.swingViewer.util.Camera#setViewCenter(double,
  * double, double)
  */
 public void setViewCenter(double x, double y, double z) {
   setAutoFitView(false);
   center.set(x, y, z);
   graph.graphChanged = true;
 }