private void updateScale(double oldScale, double newScale, SVGElement svg, int cx, int cy) {

    double zoomFactor = newScale / oldScale;
    // (x in new coord system - x in old coord system)/x coordinate
    SVGGElement g = m_svgViewPort.cast();

    if (cx == 0) {
      cx = (int) (Math.ceil(svg.getOffsetWidth() / 2.0) - 1);
    }

    if (cy == 0) {
      cy = (int) (Math.ceil(svg.getOffsetHeight() / 2.0) - 1);
    }

    SVGPoint p = svg.createSVGPoint();
    p.setX(cx);
    p.setY(cy);
    p = p.matrixTransform(g.getCTM().inverse());

    SVGMatrix m =
        svg.createSVGMatrix()
            .translate(p.getX(), p.getY())
            .scale(zoomFactor)
            .translate(-p.getX(), -p.getY());
    SVGMatrix ctm = g.getCTM().multiply(m);

    consoleLog("zoomFactor: " + zoomFactor + " oldScale: " + oldScale + " newScale:" + newScale);
    D3.d3()
        .select(m_svgViewPort)
        .transition()
        .duration(1000)
        .attr("transform", matrixTransform(ctm));
  }
    public PanObject(Element draggableElement, Element containerElement) {
      super(draggableElement, containerElement);

      SVGGElement g = draggableElement.cast();
      m_stateTf = g.getCTM().inverse();

      m_stateOrigin = getEventPoint(D3.getEvent()).matrixTransform(m_stateTf);
    }
  private void drawGraph(GWTGraph g, boolean now) {

    if (now) {
      m_graphDrawerNoTransition.updateGraph(g);
    } else {
      m_graphDrawer.updateGraph(g);
    }

    // TODO: working here
    SVGRect bbox = getSVGElement().getBBox();
    SVGGElement map = m_svgViewPort.cast();
    SVGRect mapBbox = map.getBBox();
    double referenceScale = 0.4;
    int x = bbox.getX();
    int y = bbox.getY();
    int width = (int) (mapBbox.getWidth() * referenceScale);
    int height = (int) (mapBbox.getHeight() * referenceScale);

    int viewPortWidth = (int) (m_svg.getOffsetWidth() * referenceScale);
    int viewPortHeight = (int) (m_svg.getOffsetHeight() * referenceScale);

    m_referenceMapViewport.setAttribute("width", "" + viewPortWidth);
    m_referenceMapViewport.setAttribute("height", "" + viewPortHeight);

    m_referenceMap.setAttribute(
        "transform",
        "translate("
            + (m_svg.getOffsetWidth() - width)
            + " "
            + (m_svg.getOffsetHeight() - height)
            + ")");

    // TODO: Fix this calc

    m_scaledMap.setAttribute(
        "viewBox", x + " " + y + " " + mapBbox.getWidth() + " " + mapBbox.getHeight());
  }
    @Override
    public void move() {
      Event event = D3.getEvent().cast();
      SVGPoint p = getEventPoint(event).matrixTransform(m_stateTf);

      SVGElement svg = getContainerElement().cast();
      SVGGElement g = getDraggableElement().cast();
      SVGRect gBox = g.getBBox();

      SVGMatrix m =
          m_stateTf
              .inverse()
              .translate(p.getX() - m_stateOrigin.getX(), p.getY() - m_stateOrigin.getY());

      double mapWidth = gBox.getWidth() * m.getA();
      double mapHeight = gBox.getHeight() * m.getA();

      double boundaryX = calculateBoundsX(mapWidth, svg.getOffsetWidth(), m.getE());

      double boundaryY = calculateBoundsY(mapHeight, svg.getOffsetHeight(), m.getF());

      String matrixTransform =
          "matrix(" + m.getA() + ", " + m.getB() + ", " + m.getC() + ", " + m.getD() + ", "
              + boundaryX + ", " + boundaryY + ")";

      getDraggableElement().setAttribute("transform", matrixTransform);

      // Updating the reference map
      // TODO: this needs to be reworked a little its off
      double viewPortWidth = (getContainerElement().getOffsetWidth() / m.getA()) * 0.4;
      double viewPortHeight = (getContainerElement().getOffsetHeight() / m.getA()) * 0.4;
      m_referenceMapViewport.setAttribute("width", "" + viewPortWidth);
      m_referenceMapViewport.setAttribute("height", "" + viewPortHeight);
      m_referenceMapViewport.setAttribute("x", "" + (-boundaryX * 0.4));
      m_referenceMapViewport.setAttribute("y", "" + (-boundaryY * 0.4));
    }
 private void setCTM(SVGGElement elem, SVGMatrix matrix) {
   elem.setAttribute("transform", matrixTransform(matrix));
 }