Skip to main content Skip to footer

Add Datapoint Symbols Dynamically to C1Chart

As a general rule, Silverlight/WPF performance degrades with an increase in the number of objects in visual tree. For instance, take the LineSymbol Chart. When a large number of data points are plotted, the rendering is slow, as the large number of datapoint Symbols makes the visual tree quite large. In extreme cases, this can even make user interaction quite difficult.

Simple charts like Line Charts are much better; they represent data at a much faster pace because there are no datapoint "symbols" and the chart interaction is easier and faster. Unfortunately, line charts are limited because of the lack of the information related to the datapoints which can be useful in some scenarios. In LineSymbol charts, we can use PointToolTip/Labels to show that information but how can we achieve the same thing with simple Line charts?

This post shows you how to add datapoint "symbols" dynamically to C1Charts and show tooltips related to datapoints. The idea is simply to listen to the MouseMove event on chart and find if the current mouse position is nearer to any datapoint. In cases where you locate a point that is closer, you may add a symbol to the chart view at the required position. In this case, we would be using an ellipse symbol as the datapoint symbol.

Let's start by creating a simple Line chart and populating it with some basic data.

 ObservableCollection pointssource = new ObservableCollection();  

 chart.ChartType = ChartType.Line;  
            Random r=new Random();  
            for (int i = 0; i <= 1500; i  )  
            {  
                pointssource.Add(new Point() { X =i  r.NextDouble(), Y = r.Next(1,1000) });  
            }  
            dataseries.ItemsSource = pointssource;  
            dataseries.XValueBinding = new Binding("X");  
            dataseries.ValueBinding = new Binding("Y");    

            chart.Data.Children.Add(dataseries);

The chart MouseMove event which tracks the current position and adds a symbol would be like this:-

void chart_MouseMove(object sender, MouseEventArgs e)  
        {  
            chart.View.Children.Remove(pointsymbol);    

            Rect plotrect = chart.View.PlotRect;  
            Point ptdata = chart.View.PointToData(e.GetPosition(chart));  
            Point ptview = chart.View.GetPosition(e);  

            // line  
            line.X1 = line.X2 = ptview.X;  
            line.Y1 = plotrect.Top;  
            line.Y2 = plotrect.Bottom;  

            // text  
            Canvas.SetLeft(text, line.X1);  
            Canvas.SetTop(text, line.Y1);  

            if (IsPointNear(ptdata) == true)  
            {  
                Point dpoint = chart.View.PointFromData(new Point() { X = pointssource[currentindex].X, Y = pointssource[currentindex].Y });  
                chart.View.Children.Add(pointsymbol);  
                Canvas.SetLeft(pointsymbol, dpoint.X - pointsymbol.Width / 2);  
                Canvas.SetTop(pointsymbol, dpoint.Y - pointsymbol.Height / 2);  
                ToolTipService.SetToolTip(pointsymbol, string.Format("{0},{1}", pointssource[currentindex].X, pointssource[currentindex].Y));  
            }  

            // print data coordinates  
            text.Text = string.Format("{0:0.00},{1:0.00}", ptdata.X, ptdata.Y);  
        }

The "IsPointNear" is an important function which determines if the current mouse position is close to any of the datapoint plotted on chart by calculating the distance between datapoints and current mouse position.

  bool IsPointNear(Point p)  
        {  
            for (int i = 0; i < pointssource.Count; i  )  
            {  
                if (((Math.Abs(p.X - pointssource[i].X)) < 5) && ((Math.Abs(p.Y - pointssource[i].Y)) < 5))  
                {  
                    currentindex=i;  
                    return true;  

                }  
            }  
            return false;  
    }

If you'd like to try this out, please download the attached sample. ChartDynamicSymbolsSL

MESCIUS inc.

comments powered by Disqus