Charts are mainly used for visualizing the data so that it helps the end users for analyzing data in a better way. We generally use ChartLabelsToolTips, ValueLabels etc. to make the Chart as user friendly as possible. Another way of making the chart more readable, is to add a tracker which can move with the mouse cursor showing details of the corresponding datapoint.

In this blog, we would discuss how you can add a Tracker in C1Chart.

C1Chart has a built in DataHighlight object which is accessible through the ChartData object. You can use this object to get the PointIndex and SeriesIndex of the highlighted datapoint. However, in order to use the DataHighlight object, each point must have a symbol, even if it is of zero size.

The idea is to get the DataHighlight object using Highlight property of C1Chart, check if the mouse is in the PlotArea using ChartRegionFromCoord method and then, find the closest X Coordinate in the MouseMove event. Here is the code snippet that implements it for

private void Form1_Load(object sender, EventArgs e)
{
//get the ChartData object
ChartData cd = c1Chart1.ChartGroups.Group0.ChartData;

// Set all the series symbols as zero size. If the shape is none, then it will not highlight
ChartDataSeriesCollection cdsc = cd.SeriesList;
foreach(ChartDataSeries cds in cdsc)
{
cds.SymbolStyle.Shape = SymbolShapeEnum.Dot;
cds.SymbolStyle.Size = 0;
}

// preset the highlight object parameters for the group.
DataHighlight dhl = cd.HighLight;
dhl.SymbolStyle.Color = Color.Blue;
dhl.SymbolStyle.Shape = SymbolShapeEnum.Dot;
dhl.SymbolStyle.Size = 10;

// Custom indicates user code will handle setting the series and point index.
dhl.Activation = HighlightActivationEnum.Custom;

// Set up the mouse move handler.
c1Chart1.MouseMove += new MouseEventHandler(c1Chart1_MouseMove);
}

void c1Chart1_MouseMove(object sender, MouseEventArgs e)
{
// always get the Highlight object.
DataHighlight dhl = c1Chart1.ChartGroups.Group0.ChartData.HighLight;

// if both are changed to valid values, then something needs to be highlighted
int seriesIndex = -1, pointIndex = -1;

// check if the mouse is in the PlotArea.
if (c1Chart1.ChartRegionFromCoord(e.X, e.Y) == ChartRegionEnum.PlotArea)
{
ChartGroup grp = c1Chart1.ChartGroups.Group0;
int dist = 0;

// find the closest XCoord.
if(grp.CoordToDataIndex(e.X, e.Y, CoordinateFocusEnum.XCoord, ref seriesIndex, ref pointIndex, ref dist))
{
// if there are multiple series in the chart, then find the closest series.
if (grp.CoordToSeriesIndex(e.X, e.Y, PlotElementEnum.Series, ref seriesIndex, ref dist))
{
dhl.SeriesIndex = seriesIndex;
dhl.PointIndex = pointIndex;
}
}
}

// if either of these indices is has not been set, then clear the highlight object.
if (seriesIndex == -1 || pointIndex == -1)
{
dhl.SeriesIndex = -1;
dhl.PointIndex = -1;
}
}


If you don't want to use DataHighlight object then you can achieve the same using PointStyles as well. There will some minor changes in the above code like:


private void Form1_Load(object sender, EventArgs e)
{
...

PointStyle ps = c1Chart1.ChartGroups.Group0.ChartData.PointStylesList.AddNewPointStyle();
ps.SymbolStyle.Shape = SymbolShapeEnum.Dot;
ps.SymbolStyle.Size = 10;
ps.SymbolStyle.Color = Color.Blue;
ps.PointIndex = -1;
ps.SeriesIndex = -1;
ps.Label = "trackingBall";

...
}

void c1Chart1_MouseMove(object sender, MouseEventArgs e)
{
ChartGroup grp = c1Chart1.ChartGroups.Group0;
PointStyle ps = grp.ChartData.PointStylesList[0];

...
if (grp.CoordToSeriesIndex(e.X, e.Y, PlotElementEnum.Series, ref seriesIndex, ref dist))
{
ps.PointIndex = pointIndex;
ps.SeriesIndex = seriesIndex;
}
...
// if either of these indices is has not been set, then clear the PointStyle object.
if (seriesIndex == -1 || pointIndex == -1)
{
ps.PointIndex = -1;
ps.SeriesIndex = -1;
}
}


ChartTracker

Download Source Code - C#
Download Source Code - VB