private void updateShape(final int oldWidth, final int oldHeight) {
   if (getShape() != null && getWidth() > 0f && getHeight() > 0f) {
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             if (graphController.isAnimatable())
               animate(
                   animateShape,
                   polygon,
                   graphController.getAnimationSpeed(),
                   calculatePoints(getShape(), oldWidth, oldHeight),
                   calculatePoints(getShape(), getWidth(), getHeight()));
             else {
               polygon.setAttribute(
                   SVG_POINTS_ATTRIBUTE, calculatePoints(getShape(), getWidth(), getHeight()));
               iteration.setAttribute(
                   SVG_TRANSFORM_ATTRIBUTE, "translate(" + (getWidth() - 1.5) + " 5.5)");
               error.setAttribute(
                   SVG_TRANSFORM_ATTRIBUTE,
                   "translate(" + (getWidth() - 1.5) + " " + (getHeight() - 1) + ")");
             }
           }
         });
   }
 }
 @Override
 public void setLabel(final String label) {
   super.setLabel(label);
   graphController.updateSVGDocument(
       new Runnable() {
         @Override
         public void run() {
           labelText.setData(label);
         }
       });
 }
 @Override
 public void setIteration(final int iteration) {
   graphController.updateSVGDocument(
       new Runnable() {
         @Override
         public void run() {
           if (iteration > 0) iterationText.setData(String.valueOf(iteration));
           else iterationText.setData("");
         }
       });
 }
 @Override
 public boolean removeSubgraph(Graph subgraph) {
   if (subgraph instanceof SVGGraph) {
     final SVGGraph svgGraph = (SVGGraph) subgraph;
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             mainGroup.removeChild(svgGraph.getSVGElement());
           }
         });
   }
   return super.removeSubgraph(subgraph);
 }
 @Override
 public boolean removeNode(GraphNode node) {
   if (node instanceof SVGGraphNode) {
     final SVGGraphNode svgGraphNode = (SVGGraphNode) node;
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             mainGroup.removeChild(svgGraphNode.getSVGElement());
           }
         });
   }
   return super.removeNode(node);
 }
 @Override
 public void setCompleted(final float complete) {
   super.setCompleted(complete);
   graphController.updateSVGDocument(
       new Runnable() {
         @Override
         public void run() {
           Dimension size = getSize();
           Point position = getPosition();
           completedPolygon.setAttribute(
               SVG_POINTS_ATTRIBUTE,
               calculatePoints(getShape(), (int) (size.width * complete), size.height));
           completedPolygon.setAttribute(
               SVG_TRANSFORM_ATTRIBUTE, "translate(" + position.x + " " + position.y + ")");
         }
       });
 }
 @Override
 public void addSubgraph(Graph subgraph) {
   super.addSubgraph(subgraph);
   if (subgraph instanceof SVGGraph) {
     final SVGGraph svgGraph = (SVGGraph) subgraph;
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             float opacity = svgGraph.getOpacity();
             svgGraph.setOpacity(0);
             mainGroup.appendChild(svgGraph.getSVGElement());
             svgGraph.setOpacity(opacity);
           }
         });
   }
 }
 @Override
 public void addNode(GraphNode node) {
   super.addNode(node);
   if (node instanceof SVGGraphNode) {
     final SVGGraphNode svgGraphNode = (SVGGraphNode) node;
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             float opacity = svgGraphNode.getOpacity();
             svgGraphNode.setOpacity(0);
             mainGroup.appendChild(svgGraphNode.getSVGElement());
             svgGraphNode.setOpacity(opacity);
           }
         });
   }
 }
 @Override
 public void addEdge(GraphEdge edge) {
   if (edge instanceof SVGGraphEdge) {
     final SVGGraphEdge svgGraphEdge = (SVGGraphEdge) edge;
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             float opacity = svgGraphEdge.getOpacity();
             svgGraphEdge.setOpacity(0);
             mainGroup.appendChild(svgGraphEdge.getSVGElement());
             svgGraphEdge.setOpacity(opacity);
           }
         });
   }
   super.addEdge(edge);
 }
 @Override
 public void setPosition(final Point position) {
   final Point oldPosition = getPosition();
   if (position != null && !position.equals(oldPosition)) {
     super.setPosition(position);
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             if (graphController.isAnimatable())
               animate(
                   animatePosition,
                   polygon,
                   graphController.getAnimationSpeed(),
                   oldPosition.x + ", " + oldPosition.y,
                   position.x + ", " + position.y);
             else
               polygon.setAttribute(
                   SVG_TRANSFORM_ATTRIBUTE, "translate(" + position.x + " " + position.y + ")");
           }
         });
   }
 }
 @Override
 public void setLabelPosition(final Point labelPosition) {
   final Point oldLabelPosition = getLabelPosition();
   if (labelPosition != null && !labelPosition.equals(oldLabelPosition)) {
     super.setLabelPosition(labelPosition);
     graphController.updateSVGDocument(
         new Runnable() {
           @Override
           public void run() {
             if (graphController.isAnimatable() && oldLabelPosition != null)
               animate(
                   animateLabel,
                   labelGroup,
                   graphController.getAnimationSpeed(),
                   oldLabelPosition.x + ", " + oldLabelPosition.y,
                   labelPosition.x + ", " + labelPosition.y);
             else
               labelGroup.setAttribute(
                   SVG_TRANSFORM_ATTRIBUTE,
                   "translate(" + labelPosition.x + " " + labelPosition.y + ")");
           }
         });
   }
 }
  public SVGGraph(SVGGraphController graphController) {
    super(graphController);
    this.graphController = graphController;

    mouseClickAction = new SVGMouseClickEventListener(this);
    mouseMovedAction = new SVGMouseMovedEventListener(this);
    mouseUpAction = new SVGMouseUpEventListener(this);
    mouseOverAction = new SVGMouseOverEventListener(this);
    mouseOutAction = new SVGMouseOutEventListener(this);

    mainGroup = graphController.createGElem();
    mainGroup.setAttribute(SVG_FONT_SIZE_ATTRIBUTE, "10");
    mainGroup.setAttribute(SVG_FONT_FAMILY_ATTRIBUTE, "Helvetica");
    mainGroup.setAttribute(SVG_STROKE_ATTRIBUTE, CSS_BLACK_VALUE);
    mainGroup.setAttribute(SVG_STROKE_DASHARRAY_ATTRIBUTE, CSS_NONE_VALUE);
    mainGroup.setAttribute(SVG_STROKE_WIDTH_ATTRIBUTE, "1");
    mainGroup.setAttribute(SVG_FILL_ATTRIBUTE, CSS_NONE_VALUE);

    EventTarget t = (EventTarget) mainGroup;
    t.addEventListener(SVG_CLICK_EVENT_TYPE, mouseClickAction, false);
    t.addEventListener(SVG_MOUSEMOVE_EVENT_TYPE, mouseMovedAction, false);
    t.addEventListener(SVG_MOUSEUP_EVENT_TYPE, mouseUpAction, false);
    // t.addEventListener(SVGConstants.SVG_MOUSEOVER_EVENT_TYPE, mouseOverAction, false);
    // t.addEventListener(SVGConstants.SVG_MOUSEOUT_EVENT_TYPE, mouseOutAction, false);

    polygon = graphController.createPolygon();
    mainGroup.appendChild(polygon);

    completedPolygon = graphController.createPolygon();
    completedPolygon.setAttribute(SVG_POINTS_ATTRIBUTE, calculatePoints(getShape(), 0, 0));
    completedPolygon.setAttribute(SVG_FILL_ATTRIBUTE, COMPLETED_COLOUR);
    // completedPolygon.setAttribute(SVGConstants.SVG_FILL_OPACITY_ATTRIBUTE, "0.8");
    // completedPolygon.setAttribute(SVG_STROKE_ATTRIBUTE, SVG_NONE_VALUE);
    mainGroup.appendChild(completedPolygon);

    labelText = graphController.createText("");
    label = graphController.createText(labelText);
    label.setAttribute(SVG_TEXT_ANCHOR_ATTRIBUTE, SVG_MIDDLE_VALUE);
    label.setAttribute(SVG_FILL_ATTRIBUTE, CSS_BLACK_VALUE);
    label.setAttribute(SVG_STROKE_ATTRIBUTE, SVG_NONE_VALUE);
    labelGroup = graphController.createGElem();
    labelGroup.appendChild(label);
    mainGroup.appendChild(labelGroup);

    iterationText = graphController.createText("");
    iteration = graphController.createText(iterationText);
    iteration.setAttribute(SVG_TEXT_ANCHOR_ATTRIBUTE, SVG_END_VALUE);
    iteration.setAttribute(SVG_FONT_SIZE_ATTRIBUTE, "6");
    iteration.setAttribute(SVG_FONT_FAMILY_ATTRIBUTE, "sans-serif");
    iteration.setAttribute(SVG_FILL_ATTRIBUTE, CSS_BLACK_VALUE);
    iteration.setAttribute(SVG_STROKE_ATTRIBUTE, SVG_NONE_VALUE);
    polygon.appendChild(iteration);

    errorsText = graphController.createText("");
    error = graphController.createText(errorsText);
    error.setAttribute(SVG_TEXT_ANCHOR_ATTRIBUTE, SVG_END_VALUE);
    error.setAttribute(SVG_FONT_SIZE_ATTRIBUTE, "6");
    error.setAttribute(SVG_FONT_FAMILY_ATTRIBUTE, "sans-serif");
    error.setAttribute(SVG_FILL_ATTRIBUTE, CSS_BLACK_VALUE);
    error.setAttribute(SVG_STROKE_ATTRIBUTE, SVG_NONE_VALUE);
    polygon.appendChild(error);

    animateShape =
        createAnimationElement(graphController, SVG_ANIMATE_TAG, SVG_POINTS_ATTRIBUTE, null);

    animatePosition =
        createAnimationElement(
            graphController,
            SVG_ANIMATE_TRANSFORM_TAG,
            SVG_TRANSFORM_ATTRIBUTE,
            TRANSFORM_TRANSLATE);

    animateLabel =
        createAnimationElement(
            graphController,
            SVG_ANIMATE_TRANSFORM_TAG,
            SVG_TRANSFORM_ATTRIBUTE,
            TRANSFORM_TRANSLATE);

    delegate = new SVGGraphElementDelegate(graphController, this, mainGroup);
  }