public override void OnModifierMouseMove(ModifierMouseArgs e) { base.OnModifierMouseMove(e); var allSeries = this.ParentSurface.RenderableSeries; // Translates the mouse point to chart area, e.g. when you have left axis var pt = GetPointRelativeTo(e.MousePoint, this.ModifierSurface); // Position the rollover line _line.Y1 = 0; _line.Y2 = ModifierSurface.ActualHeight; _line.X1 = pt.X; _line.X2 = pt.X; ClearModifierSurface(); // Add the rollover line to the ModifierSurface, which is just a canvas over the main chart area, on top of series this.ModifierSurface.Children.Add(_line); // Add the rollover points to the surface var hitTestResults = allSeries.Select(x => x.VerticalSliceHitTest(pt)).ToArray(); foreach (var hitTestResult in hitTestResults) { const int markerSize = 7; // Create one ellipse per HitTestResult and position on the canvas var ellipse = new Ellipse() { Width = markerSize, Height = markerSize, Fill = _line.Stroke, IsHitTestVisible = false, Tag = typeof(SimpleRolloverModifier) }; //ToolTip = Canvas.SetLeft(ellipse, hitTestResult.HitTestPoint.X - markerSize * 0.5); Canvas.SetTop(ellipse, hitTestResult.HitTestPoint.Y - markerSize * 0.5); this.ModifierSurface.Children.Add(ellipse); // Create one label per HitTestResult and position on the canvas // TODO: Could this be templated? Yes it could! var text = new Border() { IsHitTestVisible = false, BorderBrush = TextForeground, BorderThickness = new Thickness(1), Background = LineBrush, CornerRadius = new CornerRadius(2, 2, 2, 2), Tag = typeof(SimpleRolloverModifier), Child = new TextBlock() { Text = string.Format("X: {0}, Y: {1}", XAxis.FormatCursorText(hitTestResult.XValue), YAxis.FormatCursorText(hitTestResult.YValue)), FontSize = 11, Margin = new Thickness(3), Foreground = TextForeground, } }; Canvas.SetLeft(text, hitTestResult.HitTestPoint.X + 5); Canvas.SetTop(text, hitTestResult.HitTestPoint.Y - 5); this.ModifierSurface.Children.Add(text); } }