// Apply node constraints to node size
    private Vector2 ComputeNodeSize(Vector2 scale, NodeConstraints nodeConstraints)
    {
        var nodeSize = new Vector2(nodeConstraints.maximumNormalizedNodeSize * scale.x,
                nodeConstraints.maximumNormalizedNodeSize * scale.y);

        // Adjust aspect ratio after scaling
        float currentAspectRatio = nodeSize.x / nodeSize.y;

        if (currentAspectRatio > nodeConstraints.aspectRatio)
        {
            // Shrink x dimension
            nodeSize.x = nodeSize.y * nodeConstraints.aspectRatio;
        }
        else
        {
            // Shrink y dimension
            nodeSize.y = nodeSize.x / nodeConstraints.aspectRatio;
        }

        // If node size is still too big, scale down
        if (nodeSize.x > nodeConstraints.maximumNodeSizeInPixels)
        {
            nodeSize *= nodeConstraints.maximumNodeSizeInPixels / nodeSize.x;
        }

        if (nodeSize.y > nodeConstraints.maximumNodeSizeInPixels)
        {
            nodeSize *= nodeConstraints.maximumNodeSizeInPixels / nodeSize.y;
        }
        return nodeSize;
    }
    public void Draw(ILayoutAlgorithm layout, Rect totalDrawingArea, NodeConstraints nodeConstraints)
    {
        PrepareLegend(layout.vertices);

        var drawingArea = new Rect(totalDrawingArea);
        var legendArea = new Rect(totalDrawingArea);
        legendArea.width = EstimateLegendWidth() + k_BorderSize * 2;
        legendArea.x = drawingArea.xMax - legendArea.width;
        drawingArea.width -=  legendArea.width;

        DrawGraph(layout, drawingArea, nodeConstraints);
        DrawLegend(legendArea);
    }
    private void DrawGraph(ILayoutAlgorithm layout, Rect drawingArea, NodeConstraints nodeConstraints)
    {
        // add border, except on right-hand side where the legend will provide necessary padding
        drawingArea = new Rect(drawingArea.x + k_BorderSize,
                drawingArea.y + k_BorderSize,
                drawingArea.width - k_BorderSize,
                drawingArea.height - k_BorderSize * 2);

        var b = new Bounds(Vector3.zero, Vector3.zero);
        foreach (var c in layout.vertices)
        {
            b.Encapsulate(new Vector3(c.position.x, c.position.y, 0.0f));
        }

        // Increase b by maximum node size (since b is measured between node centers)
        b.Expand(new Vector3(nodeConstraints.maximumNormalizedNodeSize, nodeConstraints.maximumNormalizedNodeSize, 0));

        var scale = new Vector2(drawingArea.width / b.size.x, drawingArea.height / b.size.y);
        var offset = new Vector2(-b.min.x, -b.min.y);

        Vector2 nodeSize = ComputeNodeSize(scale, nodeConstraints);

        GUI.BeginGroup(drawingArea);

        foreach (var e in layout.edges)
        {
            Vector2 v0 = ScaleVertex(layout.vertices[e.source].position, offset, scale);
            Vector2 v1 = ScaleVertex(layout.vertices[e.destination].position, offset, scale);
            DrawEdge(v0, v1, layout.vertices[e.source].propagatedWeight);
        }

        int index = 0;
        foreach (var v in layout.vertices)
        {
            DrawNode(v, ScaleVertex(v.position, offset, scale) - nodeSize / 2, nodeSize, index.ToString());
            index++;
        }

        GUI.EndGroup();
    }