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