If there are multiple players on a chart is it possible to have a unified tooltip that displays the current Y value of each layer currently in contact with the vertical crosshair without having to have the cursor touching each layer individually?
Mike and Hans,
You need a bit of a different approach for the CategoryDateTimeXAxis. The unscaled axis values represent ticks that you can convert into a DateTime. So if you do a new DateTime on the xAxisValue in the code above you get the actual DateTime value at the cursor.However, because of the nature of this type of Axis, that doesn't correlate to an index, letting you lookup the closest item in the collection.So you need a bit more code to get you from the DateTime value of the cursor to the represented source item.You will probably want to make some performance modifications depending on whether your source collection is sorted by date or massive.The changed xaml:
<local:HoveredCategoryItemsBehavior CategoryOffset="True"> <local:HoveredCategoryItemsBehavior.ItemComparer> <local:TestDataItemComparer /> </local:HoveredCategoryItemsBehavior.ItemComparer> </local:HoveredCategoryItemsBehavior>
The changed code:
public IComparer<object> ItemComparer { get; set; } void Chart_PropertyUpdated( object sender, PropertyUpdatedEventArgs e) { if (e.PropertyName == "CrosshairPoint") { foreach (CategorySeries series in _owner.Series.Where((s) => s is CategorySeries)) { CategoryAxisBase x = series.XAxis; NumericYAxis y = series.YAxis; Rect viewportRect = GetViewportRect( series, x, y); Point p = (Point)e.NewValue; double left; double right; double top; double bottom; GetInViewAxisBounds(x, y, viewportRect, out left, out right, out top, out bottom); double windowX = (p.X - _owner.WindowRect.Left) / _owner.WindowRect.Width; double xAxisValue = left + (windowX * (right - left)); if (CategoryOffset) { xAxisValue -= .5; } object item = null; if (!double.IsInfinity(xAxisValue) && !double.IsNaN(xAxisValue) && xAxisValue >= 0 && series.ItemsSource != null) { //note, you certainly want to do something more //efficient here, but its complexity depends on //your data and whether it is pre-sorted, etc. List<object> list = x.ItemsSource.OfType<object>().ToList(); list.Sort(ItemComparer); int index = list.BinarySearch(new DateTime((long)xAxisValue), ItemComparer); if (index < 0) { index = (~index) - 1; } //this should actually determine if index or //index + 1 is closer to the value we are searching for //leaving this as excercise for the reader. if (index > 0 && index < list.Count) { item = list[index]; } if (item != null) { HoveredItems .UpdateSeriesItem(series, item); } } } } }
The ItemComparer for the sample data:
public class TestDataItemComparer : IComparer<object> { public int Compare(object x, object y) { DateTime xDate = DateTime.MinValue; DateTime yDate = DateTime.MaxValue; if (x is TestDataItem) { xDate = (x as TestDataItem).Date; } if (y is TestDataItem) { yDate = (y as TestDataItem).Date; } if (x is DateTime) { xDate = (DateTime)x; } if (y is DateTime) { yDate = (DateTime)y; } return DateTime.Compare(xDate, yDate); } }
Hope this helps!-Graham
Hi,
I've searched around several hours, but I didn't find a solution to get the y-axis values of the series at the current cursor position.
I am also using the CategoryDateTimeXAxis. I would prefer if it would be possible to have the Timestamp of the current cursor position at the chart SeriesCursorMouseMove event. Then I can select the responsible values for my own in the data source.
Will such a feature be added in the future or do I have to write also an eMail to the product management?
RegardsJohannes
Graham,
in addition at use of a CategoryDateTimeXAxis the item of ChartEventArgs in the event SeriesCursorMouseMove is always null.
I have the same problem as Mike. It would be great if you could provide a solution.
Thanks,Hans
I have switched over to the CategoryDateTimeXAxis and this behavior to get the y values for the current cursor x position no longer works. The GetUnscaledValue seems to be where the difference is. For some reason pulling the left and right values returns huge numbers (10 to the 14th power for example). I am unfamiliar with exactly how this function works so I wanted to check to see if you knew what I am missing.
Thanks,Mike