Applies to: Nevron Chart for .NET

How how to apply a range of colors to a line series?

This article discusses how to apply a range of colors to a line series.

It is a common requirement to plot a line where certain ranges of values are color coded. This improves the visual impact and makes the chart more readable.

The following code shows how to apply two color zones to a line series:

[C#]

private void Form1_Load(object sender, EventArgs e)
{
       NCartesianChart      chart = (NCartesianChart)nChartControl1.Charts[0];
 
       NLineSeries line = new NLineSeries();
       line.UseXValues = true;
       line.DataLabelStyle.Visible = false;
 
       chart.Series.Add(line);
 
       for (int i = 0; i < 100; i++)
       {
             line.Values.Add(Math.Cos(i * 180.0 / Math.PI) * 50);
             line.XValues.Add(i);
       }
 
       ApplyLineColorRanges(new NRange1DD[] { new NRange1DD(-50, -20), new NRange1DD(20, 50) },
                                         new Color[] { Color.Blue, Color.Red }, line);
}
///
/// </summary>
/// <param name="ranges"></param>
/// <param name="colors"></param>
/// <param name="line"></param>
private static void ApplyLineColorRanges(NRange1DD[] ranges, Color[] colors, NLineSeries line)
{
       Color defaultColor = line.BorderStyle.Color;
       NLength width = line.BorderStyle.Width;
 
       // pass 1 split all lines that are intersected by range
       for (int i = 0; i < ranges.Length; i++)
       {
             NRange1DD range = ranges[i];
 
             SplitLineAtY(range.Begin, line);
             SplitLineAtY(range.End, line);
       }
 
       for (int i = 0; i < ranges.Length; i++)
       {
             ApplyColorRange(width, colors[i], ranges[i], line);
       }
}
/// <summary>
/// Splits the line at the specified y cooridnate.
/// </summary>
/// <param name="y"></param>
/// <param name="line"></param>
private static void SplitLineAtY(double y, NLineSeries line)
{
       int count = line.Values.Count;
 
       for (int i = 1; i < count; i++)
       {
             double y1 = (double)line.Values[i - 1];
             double y2 = (double)line.Values[i];
 
             if (y1 == y2)
                    continue;
 
             if (y1 < y2)
             {
                    // ascending
                    if (y1 >= y)
                           continue;
 
                    if (y2 <= y)
                           continue;
             }
             else
             {
                    // descending
                    if (y2 >= y)
                           continue;
 
                    if (y1 <= y)
                           continue;
             }
 
             // split
             double x1 = (double)line.XValues[i - 1];
             double x2 = (double)line.XValues[i];
 
             double dy = y2 - y1;
             double dx = x2 - x1;
 
             double x3 = x1 + dx * (y - y1) / dy;
 
             line.XValues.Insert(i, x3);
             line.Values.Insert(i, y);
 
             i++;
             count++;
       }
}
/// <summary>
/// Applies the specified color to the range
/// </summary>
/// <param name="width"></param>
/// <param name="color"></param>
/// <param name="range"></param>
/// <param name="line"></param>
private static void ApplyColorRange(NLength width, Color color, NRange1DD range, NLineSeries line)
{
       int count = line.Values.Count - 1;
 
       for (int i = 0; i < count; i++)
       {
             double y1 = (double)line.Values[i];
             double y2 = (double)line.Values[i + 1];
 
             if (range.Contains(y1, 0.0001) && range.Contains(y2, 0.0001))
             {
                    line.BorderStyles[i] = new NStrokeStyle(width, color);
              }
       }
}

[VB.NET]
Private Sub Form1_Load(sender As Object, e As EventArgs)
         Dim chart As NCartesianChart = DirectCast(nChartControl1.Charts(0), NCartesianChart)
 
         Dim line As New NLineSeries()
         line.UseXValues = True
         line.DataLabelStyle.Visible = False
 
         chart.Series.Add(line)
 
         For i As Integer = 0 To 99
                 line.Values.Add(Math.Cos(i * 180.0 / Math.PI) * 50)
                 line.XValues.Add(i)
         Next
 
         ApplyLineColorRanges(New NRange1DD() {New NRange1DD(-50, -20), New NRange1DD(20, 50)}, New Color() {Color.Blue, Color.Red}, line)
End Sub
'''
''' </summary>
''' <param name="ranges"></param>
''' <param name="colors"></param>
''' <param name="line"></param>
Private Shared Sub ApplyLineColorRanges(ranges As NRange1DD(), colors As Color(), line As NLineSeries)
         Dim defaultColor As Color = line.BorderStyle.Color
         Dim width As NLength = line.BorderStyle.Width
 
         ' pass 1 split all lines that are intersected by range
         For i As Integer = 0 To ranges.Length - 1
                 Dim range As NRange1DD = ranges(i)
 
                 SplitLineAtY(range.Begin, line)
                 SplitLineAtY(range.[End], line)
         Next
 
         For i As Integer = 0 To ranges.Length - 1
                 ApplyColorRange(width, colors(i), ranges(i), line)
         Next
End Sub
''' <summary>
''' Splits the line at the specified y cooridnate.
''' </summary>
''' <param name="y"></param>
''' <param name="line"></param>
Private Shared Sub SplitLineAtY(y As Double, line As NLineSeries)
         Dim count As Integer = line.Values.Count
 
         For i As Integer = 1 To count - 1
                 Dim y1 As Double = CDbl(line.Values(i - 1))
                 Dim y2 As Double = CDbl(line.Values(i))
 
                 If y1 = y2 Then
                          Continue For
                 End If
 
                 If y1 < y2 Then
                          ' ascending
                          If y1 >= y Then
                                   Continue For
                          End If
 
                          If y2 <= y Then
                                   Continue For
                          End If
                 Else
                          ' descending
                          If y2 >= y Then
                                   Continue For
                          End If
 
                          If y1 <= y Then
                                   Continue For
                          End If
                 End If
 
                 ' split
                 Dim x1 As Double = CDbl(line.XValues(i - 1))
                 Dim x2 As Double = CDbl(line.XValues(i))
 
                 Dim dy As Double = y2 - y1
                 Dim dx As Double = x2 - x1
 
                 Dim x3 As Double = x1 + dx * (y - y1) / dy
 
                 line.XValues.Insert(i, x3)
                 line.Values.Insert(i, y)
 
                 i += 1
                 count += 1
         Next
End Sub
''' <summary>
''' Applies the specified color to the range
''' </summary>
''' <param name="width"></param>
''' <param name="color"></param>
''' <param name="range"></param>
''' <param name="line"></param>
Private Shared Sub ApplyColorRange(width As NLength, color As Color, range As NRange1DD, line As NLineSeries)
         Dim count As Integer = line.Values.Count - 1
 
         For i As Integer = 0 To count - 1
                 Dim y1 As Double = CDbl(line.Values(i))
                 Dim y2 As Double = CDbl(line.Values(i + 1))
 
                  If range.Contains(y1, 0.0001) AndAlso range.Contains(y2, 0.0001) Then
                          line.BorderStyles(i) = New NStrokeStyle(width, color)
                 End If
         Next
End Sub


Article ID: 237, Created On: 11/26/2013, Modified: 11/26/2013