0

I have a LineSeries chart. By series.IsSelectionEnabled = true; when I move the mouse over the points, I can select that node. But how can I do it when the mouse is not exactly over the point but when it's near it (above or under)? Thanks.

PS: One more thing. How can I change the color of the column when the mouse is over it so the user can tell which one of the columns he/she is going to select.

vortexwolf
  • 13,967
  • 2
  • 54
  • 72
Alireza Noori
  • 14,961
  • 30
  • 95
  • 179
  • About the second question: columns in a `ColumnSeries` have half-white half-transparent outer color when the mouse is over it. If you want to use a different color, it is not so easy and I would rather give the answer at a separate SO-question. – vortexwolf Apr 18 '11 at 15:23
  • In a LineSeries I created a custom template (with a few searches) and handled the MouseEnter and MouseLeave of the LineDataPoint's Ellipse in the handler I changed the Fill to my custom color. Now when I move my mouse over a point, it's color will change but the thing is, I want to use something like that in your code below. Is is possible? – Alireza Noori Apr 18 '11 at 16:35
  • I'm perplexed. You want to select a point on the mouse over event and not on the mouse click event, right? – vortexwolf Apr 18 '11 at 17:43
  • No, like I mentioned in the below comments, I want to provide a feedback to the MouseMove event by changing the color of the point that the user is going to select even if the mouse is not exactly over the point (and is above or below it) - Just like Google Realtime's Timeline – Alireza Noori Apr 18 '11 at 18:15
  • Despite your denial, it seems to me that it would be better to select a point if a user move the mouse near it. But the google timeline doesn't change its colors, it has stretched vertical line. Anyway, let's discuss this at another your question http://stackoverflow.com/questions/5694356/silverlight-toolkit-create-a-chart-like-google-realtime – vortexwolf Apr 18 '11 at 18:43
  • OK Thanks. As you suggested I'm going to select your answer as THE answer and continue to discuss it in the other post. – Alireza Noori Apr 18 '11 at 20:15

1 Answers1

1

I have created the example of the chart with the single LineSeries. You can click anywhere at the plot and the nearest point will be selected.

XAML (Change the ItemsSource property and other properties to yours):

    <Charting:Chart MouseLeftButtonDown="Chart_MouseLeftButtonDown">
        <Charting:Chart.Series>
            <Charting:LineSeries IsSelectionEnabled="True" ItemsSource="..." ... />
        </Charting:Chart.Series>
    </Charting:Chart>

Code-behind:

    private void Chart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var chart = sender as Chart;
        //In my example the line series is the first item of the chart series
        var line = (LineSeries)chart.Series[0];

        //Find the nearest point on the LineSeries
        var newPoint = e.GetPosition(line);
        var selectIndex = this.FindNearestPointIndex(line.Points, newPoint);

        if (selectIndex != null)
        {
            //Select a real item from the items source
            var source = line.ItemsSource as IList;
            line.SelectedItem = source[selectIndex.Value];
        }
    }

    private int? FindNearestPointIndex(PointCollection points, Point newPoint)
    {
        if (points == null || !points.Any())
            return null;

        //c^2 = a^2+b^2
        Func<Point, Point, double> getLength = (p1, p2) => Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));

        //Create the collection of points with more information
        var items = points.Select((p,i) => new { Point = p, Length = getLength(p, newPoint), Index = i });
        var minLength = items.Min(item => item.Length);

        //Uncomment if it is necessary to have some kind of sensitive area
        //if (minLength > 50)
        //    return null;

        //The index of the point with min distance to the new point
        return items.First(item => item.Length == minLength).Index;
    }

As I said this chart will select the nearest point even if you click at a great distance away from any chart point. If it isn't intended behavior, you can uncomment these lines and set any number in pixels:

//Uncomment if it is necessary to have some kind of sensitive area
if (minLength > 50)
    return null;

I have written comments, but if something isn't clear you can ask and I will explain.

vortexwolf
  • 13,967
  • 2
  • 54
  • 72
  • @vorrtex : It's great. The thing is, I think I said it wrong when I said the closes point. I meant the virtual point. That means when I click above or under a point, I want it to be selected. One more thing. Could you tell me how can I handle the MouseMove event so that moving the mouse would change the color of the point that is going to be selected by clicking on the chart? Thanks again. Great code. – Alireza Noori Apr 18 '11 at 16:30
  • I'm trying to achive something as close as possible to this: [Google Realtime TimeLine](http://www.google.ca/#q=test&hl=en&biw=1243&bih=619&prmd=ivnsfd&source=lnms&tbm=mbl&ei=FAWrTcLeBMu5tge-gMXeBw&sa=X&oi=mode_link&ct=mode&cd=9&ved=0CB8Q_AUoCA&prmdo=1&fp=e0f382b8ae76450f) (On the right) – Alireza Noori Apr 18 '11 at 16:31
  • @Alireza Noori I hasn't uderstood what the 'virtual point' means. You want to process only clicks below and above point and ignore clicks to its left and to its right? The mouseover color of chart point can be changed only if to change the `DataPointTemplate`. I can write an example, but as I see you want to create something similar to the google realtime timeline and I don't understand where the line series is used. – vortexwolf Apr 18 '11 at 17:42
  • Thanks. It doesn't have to be LineSeries. I thought that maybe I cannot create something like Google Realtime and I **have to** use LineSeries since it is less crowded than ColumnSeries when the data points are a lot. If you could provide me with something like Google Realtime it would be awesome. But if not, as you mentioned, when I click anywhere on the chart I want the point above/below it to be selected (just like Google Realtime) to make it more easy for the user to select that point. – Alireza Noori Apr 18 '11 at 18:10
  • If you look at Google Realtime, you'll notice that when you move your mouse over the chart, a selector is moving with you and the date is changing. This provides a valuable feedback to the user to make it easy to understand what point is he/she going to select. – Alireza Noori Apr 18 '11 at 18:12
  • [This commercial Control](http://www.telerik.com/help/silverlight/radtimebar-create-a-timebar-control-in-code-behind.html) is also very good. – Alireza Noori Apr 18 '11 at 18:18