private void PaintConnection(GraphConnection con, PaintState state)
{
Point srcPos = ModelToViewport(con.SourceNode.Position, state);
Point tgtPos = ModelToViewport(con.TargetNode.Position, state);
// Connections leave from the base of the source node and enter the top of the target node.
// Adjust end points to make them neatly terminate just underneath the edge of the endpoint nodes.
srcPos.Y += (int)(state._nodeDiameterHalf * 0.9f);
tgtPos.Y -= (int)(state._nodeDiameterHalf * 0.9f);
// Is any part of the connection within the viewport area?
if(!IsPointWithinViewport(srcPos, state) && !IsPointWithinViewport(tgtPos, state))
{ // Skip connection. It's outside the viewport area.
return;
}
// Create a pen for painting the connection.
// Width is related to connection strength/magnitude.
float width = (float)(con.Weight < 0.0 ? -Math.Log10(1.0 - con.Weight) : Math.Log10(1.0 + con.Weight));
width = width * state._connectionWeightToWidth * state._zoomFactor;
width = Math.Max(1f, Math.Abs(width));
Pen pen = new Pen(con.Weight < 0f ? _connectionNegative : _connectionPositive, width);
// Draw the connection line.
if(tgtPos.Y > srcPos.Y)
{
// Target is below the source. Draw a straight line.
state._g.DrawLine(pen, srcPos, tgtPos);
}
else
{
// Target is above source. Draw a back-connection.
PaintBackConnection(pen, srcPos, tgtPos,
state.GetNodeStateInfo(con.SourceNode),
state.GetNodeStateInfo(con.TargetNode),
state);
}
}