public JGraphXGraphPanel(NAR n) {
    super(new BorderLayout());

    NARGraph g = new NARGraph();
    g.add(n, IncludeEverything, new NARGraph.DefaultGraphizer(true, true, true, true, true));

    // create a visualization using JGraph, via an adapter
    jgxAdapter = new JGraphXAdapter(g) {};

    mxGraphComponent mxc = new mxGraphComponent(jgxAdapter) {};

    mxc.setAntiAlias(true);
    mxc.setConnectable(false);
    mxc.setExportEnabled(false);
    mxc.setFoldingEnabled(false);
    mxc.setPanning(true);
    mxc.setTextAntiAlias(true);

    add(new JScrollPane(mxc), BorderLayout.CENTER);

    mxFastOrganicLayout layout =
        // new mxCompactTreeLayout(jgxAdapter);
        new mxFastOrganicLayout(jgxAdapter);
    // new mxCircleLayout(jgxAdapter);
    layout.setForceConstant(150);
    layout.execute(jgxAdapter.getDefaultParent());

    /*
    mxOrganicLayout layout =
            //new mxCompactTreeLayout(jgxAdapter);
            new mxOrganicLayout(jgxAdapter);
            //new mxCircleLayout(jgxAdapter);
    layout.setEdgeLengthCostFactor(0.001);*/

    /*
    mxCompactTreeLayout layout =
            new mxCompactTreeLayout(jgxAdapter);

    layout.setLevelDistance(40);
    layout.setNodeDistance(50);
    layout.execute(jgxAdapter.getDefaultParent());*/

    jgxAdapter.setConnectableEdges(false);
    jgxAdapter.setCellsDisconnectable(false);
    jgxAdapter.setEdgeLabelsMovable(false);
    // jgxAdapter.setCellsLocked(true);
  }
  public drawGraph(Data d, String name) {

    // Create JFrame
    f = new JFrame(name);
    f.setSize(500, 500);
    f.setLocation(300, 200);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Set initial locations for vertices
    int xLoc = 20;
    int yLoc = 20;

    // Initialize temporary holding variables
    Object temp;
    String style = "";
    Vertex v;
    int i;

    // Create hashtable of IDs pointing to vertices
    Hashtable<Integer, Object> findVert = new Hashtable<Integer, Object>();

    // Create mxGraph
    final mxGraph graph = new mxGraph();
    mxGraphComponent graphComponent = new mxGraphComponent(graph);
    f.getContentPane().add(BorderLayout.CENTER, graphComponent);
    f.setVisible(true);

    Object parent = graph.getDefaultParent();
    graph.getModel().beginUpdate();

    // Read in all vertices in array list
    try {
      for (i = 0; i < d.vertices.size(); i++) {

        v = d.vertices.get(i);

        // Design vertices based on data type
        if (v.type.equals("String")) style = "fontColor=black;fillColor=#65AED";
        else if (v.type.equals("Array Reference")) style = "fontColor=black;fillColor=#74A0EF";
        else if (v.type.equals("Object Reference")) style = "fontColor=black;fillColor=#FF8330";
        else if (v.type.equals("Primitive")) style = "fontColor=black;fillColor=#BCE640";
        else if (v.type.equals("Frame")) style = "fontColor=black;fillColor=#CCCCCC";
        else style = "fontColor=black;fillColor=#FF6262";

        // Create vertices and put in hashtable
        if (!findVert.containsKey(d.vertices.get(i).id)) {
          temp =
              graph.insertVertex(parent, null, d.vertices.get(i).value, xLoc, yLoc, 80, 30, style);
          findVert.put(d.vertices.get(i).id, temp);
        }
        yLoc += 50;
        style = "";
      }

      // For each edge, create a vertex between start and finish to prevent overlapping edge labels
      try {
        for (i = 0; i < d.edges.size(); i++) {
          temp =
              graph.insertVertex(
                  parent,
                  null,
                  d.edges.get(i).name,
                  xLoc,
                  yLoc,
                  40,
                  20,
                  "strokeColor=#EEEEEE;fillColor=#EEEEEE");
          graph.insertEdge(
              parent, null, "", findVert.get(d.edges.get(i).source.id), temp, "endArrow=none");
          graph.insertEdge(parent, null, "", temp, findVert.get(d.edges.get(i).destination.id));
        }
      } catch (NullPointerException npe) {
        System.out.println(d.edges.get(i).name);
      }

    } finally {
      graph.getModel().endUpdate();
    }

    // Define layout
    mxFastOrganicLayout layout = new mxFastOrganicLayout(graph);
    layout.setForceConstant(120);

    // Layout using morphing
    graph.getModel().beginUpdate();

    try {
      layout.execute(graph.getDefaultParent());
    } finally {
      mxMorphing morph = new mxMorphing(graphComponent, 20, 1.2, 20);

      morph.addListener(
          mxEvent.DONE,
          new mxIEventListener() {

            @Override
            public void invoke(Object arg0, mxEventObject arg1) {
              graph.getModel().endUpdate();
            }
          });

      morph.startAnimation();
    }
  }