protected internal override void DataMouseEnter(object sender, MouseEventArgs e) { if (DataTooltip == null || !Hoverable) { return; } DataTooltip.Visibility = Visibility.Visible; TooltipTimer.Stop(); var senderShape = ShapesMapper.FirstOrDefault(s => Equals(s.HoverShape, sender)); if (senderShape == null) { return; } var pieSlice = senderShape.HoverShape as PieSlice; if (pieSlice == null) { return; } var xi = senderShape.Series.ScalesXAt; var yi = senderShape.Series.ScalesYAt; var labels = AxisX[xi].Labels != null ? AxisX[xi].Labels.ToArray() : null; senderShape.Shape.Opacity = .8; var vx = senderShape.ChartPoint.X; var indexedToolTip = DataTooltip as IndexedTooltip; if (indexedToolTip != null) { indexedToolTip.Header = null; //labels == null // ? (AxisX.LabelFormatter == null // ? vx.ToString(CultureInfo.InvariantCulture) // : AxisX.LabelFormatter(vx)) // : (labels.Length > vx // ? labels[(int)vx] // : ""); indexedToolTip.Data = new[] { new IndexedTooltipData { Index = (int)vx, Stroke = senderShape.HoverShape.Stroke, Fill = senderShape.HoverShape.Fill, Series = senderShape.Series, Point = senderShape.ChartPoint, Value = AxisY[yi].LabelFormatter == null ? senderShape.ChartPoint.Y.ToString(CultureInfo.InvariantCulture) : AxisY[yi].LabelFormatter(senderShape.ChartPoint.Y) } }; } var alpha = pieSlice.RotationAngle + pieSlice.WedgeAngle * .5 + 180; var alphaRad = alpha * Math.PI / 180; var sliceMidAngle = alpha - 180; DataTooltip.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var y = Canvas.ActualHeight * .5 + (sliceMidAngle > 90 && sliceMidAngle < 270 ? -1 : 0) * DataTooltip.DesiredSize.Height - Math.Cos(alphaRad) * 15; var x = Canvas.ActualWidth * .5 + (sliceMidAngle > 0 && sliceMidAngle < 180 ? -1 : 0) * DataTooltip.DesiredSize.Width + Math.Sin(alphaRad) * 15; var p = new Point(x, y); DataTooltip.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation { To = p.X, Duration = TimeSpan.FromMilliseconds(200) }); DataTooltip.BeginAnimation(Canvas.TopProperty, new DoubleAnimation { To = p.Y, Duration = TimeSpan.FromMilliseconds(200) }); pieSlice.Opacity = .8; var anim = new DoubleAnimation { To = 5, Duration = TimeSpan.FromMilliseconds(150) }; pieSlice.BeginAnimation(PieSlice.PushOutProperty, anim); }
private void DataMouseEnter(object sender, EventArgs e) { TooltipTimeoutTimer.Stop(); var source = ActualSeries.SelectMany(x => x.ActualValues.GetPoints(x)).ToList(); var senderPoint = source.FirstOrDefault(x => x.View != null && Equals(((PointView)x.View).HoverShape, sender)); if (senderPoint == null) { return; } if (Hoverable) { senderPoint.View.OnHover(senderPoint); } if (DataTooltip != null) { if (DataTooltip.Parent == null) { Panel.SetZIndex(DataTooltip, int.MaxValue); AddToView(DataTooltip); Canvas.SetTop(DataTooltip, 0d); Canvas.SetLeft(DataTooltip, 0d); } ActiveTooltip = DataTooltip; var lcTooltip = DataTooltip as IChartTooltip; if (lcTooltip == null) { throw new LiveChartsException("The current tooltip is not valid, ensure it implements IChartsTooltip"); } if (lcTooltip.SelectionMode == null) { lcTooltip.SelectionMode = senderPoint.SeriesView.Model.PreferredSelectionMode; } var coreModel = ChartFunctions.GetTooltipData(senderPoint, Model, lcTooltip.SelectionMode.Value); lcTooltip.Data = new TooltipData { XFormatter = coreModel.XFormatter, YFormatter = coreModel.YFormatter, SharedValue = coreModel.Shares, SelectionMode = lcTooltip.SelectionMode ?? TooltipSelectionMode.OnlySender, Points = coreModel.Points.Select(x => new DataPointViewModel { Series = new SeriesViewModel { PointGeometry = ((Series)x.SeriesView).PointGeometry ?? Geometry.Parse("M 0,0.5 h 1,0.5 Z"), Fill = ((Series)x.SeriesView) is IFondeable ? ((IFondeable)x.SeriesView).PointForeround : ((Series)x.SeriesView).Fill, Stroke = ((Series)x.SeriesView).Stroke, StrokeThickness = ((Series)x.SeriesView).StrokeThickness, Title = ((Series)x.SeriesView).Title, }, ChartPoint = x }).ToList() }; DataTooltip.Visibility = Visibility.Visible; DataTooltip.UpdateLayout(); var location = GetTooltipPosition(senderPoint); location = new Point(Canvas.GetLeft(DrawMargin) + location.X, Canvas.GetTop(DrawMargin) + location.Y); if (lcTooltip.IsWrapped) { var container = (FrameworkElement)DataTooltip.Parent; var positionTransform = TransformToAncestor(container); var pos = positionTransform.Transform(new Point(0, 0)); location.X += pos.X; location.Y += pos.Y; if (location.X < 0) { location.X = 0; } if (location.X + DataTooltip.ActualWidth > container.ActualWidth) { var dif = container.ActualWidth - (location.X + DataTooltip.ActualWidth); dif *= container.ActualWidth / 2 > senderPoint.ChartLocation.X ? 1 : -1; location.X += dif; } } if (DisableAnimations) { Canvas.SetLeft(DataTooltip, location.X); Canvas.SetTop(DataTooltip, location.Y); } else { DataTooltip.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(location.X, TimeSpan.FromMilliseconds(200))); DataTooltip.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(location.Y, TimeSpan.FromMilliseconds(200))); } } }
protected internal override void DataMouseEnter(object sender, MouseEventArgs e) { //this is only while we fix PCL try... if (DataTooltip == null || !Hoverable) { return; } DataTooltip.Visibility = Visibility.Visible; TooltipTimer.Stop(); var senderShape = Series.SelectMany( x => x.IsPrimitive ? x.Tracker.Primitives.Select(v => v.Value) : x.Tracker.Instances.Select(v => v.Value)) .FirstOrDefault(x => Equals(x.HoverShape, sender)); if (senderShape == null) { return; } var targetAxis = Invert ? senderShape.Series.ScalesYAt : senderShape.Series.ScalesXAt; var sibilings = Invert ? Series.SelectMany( x => x.IsPrimitive ? x.Tracker.Primitives.Select(v => v.Value) : x.Tracker.Instances.Select(v => v.Value)) .Where(s => Math.Abs(s.ChartPoint.Y - senderShape.ChartPoint.Y) < AxisY[targetAxis].S * .01) .ToList() : Series.SelectMany( x => x.IsPrimitive ? x.Tracker.Primitives.Select(v => v.Value) : x.Tracker.Instances.Select(v => v.Value)) .Where(s => Math.Abs(s.ChartPoint.X - senderShape.ChartPoint.X) < AxisX[targetAxis].S * .01) .ToList(); var first = sibilings.Count > 0 ? sibilings[0] : null; var vx = first != null ? (Invert ? first.ChartPoint.Y : first.ChartPoint.X) : 0; foreach (var sibiling in sibilings) { if (ShapeHoverBehavior == ShapeHoverBehavior.Dot) { sibiling.Shape.Stroke = sibiling.Series.Stroke; sibiling.Shape.Fill = new SolidColorBrush { Color = PointHoverColor }; } else { sibiling.Shape.Opacity = .8; } sibiling.IsHighlighted = true; } var indexedToolTip = DataTooltip as IndexedTooltip; if (indexedToolTip != null) { var fh = (Invert ? AxisY[targetAxis] : AxisX[targetAxis]).GetFormatter(); var fs = (Invert ? AxisX[targetAxis] : AxisY[targetAxis]).GetFormatter(); indexedToolTip.Header = fh(vx); indexedToolTip.Data = sibilings.Select(x => new IndexedTooltipData { Index = Series.IndexOf(x.Series), Series = x.Series, Stroke = x.Series.Stroke, Fill = x.Series.Fill, Point = x.ChartPoint, Value = fs(Invert ? x.ChartPoint.X : x.ChartPoint.Y) }).ToArray(); } //var p = GetToolTipPosition(senderShape, sibilings); DataTooltip.UpdateLayout(); DataTooltip.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var xt = senderShape.ChartPoint.X > (AxisX[targetAxis].MinLimit + AxisX[targetAxis].MaxLimit) / 2 ? senderShape.ChartPoint.Location.X - 10 - DataTooltip.DesiredSize.Width : senderShape.ChartPoint.Location.X + 10; xt += System.Windows.Controls.Canvas.GetLeft(DrawMargin); var y = sibilings.Select(s => s.ChartPoint.Location.Y).DefaultIfEmpty(0).Sum() / sibilings.Count; y = y + DataTooltip.DesiredSize.Height > ActualHeight ? y - (y + DataTooltip.DesiredSize.Height - ActualHeight) - 5 : y; var p = new Point(xt, y); DataTooltip.BeginAnimation(System.Windows.Controls.Canvas.LeftProperty, new DoubleAnimation { To = p.X, Duration = TimeSpan.FromMilliseconds(200) }); DataTooltip.BeginAnimation(System.Windows.Controls.Canvas.TopProperty, new DoubleAnimation { To = p.Y, Duration = TimeSpan.FromMilliseconds(200) }); }
private void DataMouseEnter(object sender, EventArgs e) { if (DataTooltip == null) { return; } TooltipTimeoutTimer.Stop(); if (DataTooltip.Parent == null) { Panel.SetZIndex(DataTooltip, int.MaxValue); AddToDrawMargin(DataTooltip); Canvas.SetTop(DataTooltip, 0d); Canvas.SetLeft(DataTooltip, 0d); } var source = Series.SelectMany(x => x.Values.Points); var senderPoint = source.FirstOrDefault(x => Equals(((PointView)x.View).HoverShape, sender)); if (senderPoint == null) { return; } var ax = AxisX[senderPoint.SeriesView.ScalesXAt]; var ay = AxisY[senderPoint.SeriesView.ScalesYAt]; senderPoint.View.OnHover(senderPoint); var pointsToHighlight = Enumerable.Empty <ChartPoint>(); double?shares = null; //ToDo: the tooltip should be smart enough to detect the best SelectionMode switch (DataTooltip.SelectionMode) { case TooltipSelectionMode.OnlySender: pointsToHighlight = new List <ChartPoint> { senderPoint }; break; case TooltipSelectionMode.SharedXValues: pointsToHighlight = Series.Where(x => x.ScalesXAt == senderPoint.SeriesView.ScalesXAt) .SelectMany(x => x.Values.Points) .Where(x => Math.Abs(x.X - senderPoint.X) < ax.Model.S * .01); shares = (this as PieChart) == null ? (double?)senderPoint.X : null; break; case TooltipSelectionMode.SharedYValues: pointsToHighlight = Series.Where(x => x.ScalesYAt == senderPoint.SeriesView.ScalesYAt) .SelectMany(x => x.Values.Points) .Where(x => Math.Abs(x.Y - senderPoint.Y) < ay.Model.S * .01); shares = senderPoint.Y; break; default: throw new ArgumentOutOfRangeException(); } DataTooltip.Data = new TooltipData { XFormatter = ax.Model.GetFormatter(), YFormatter = ay.Model.GetFormatter(), SharedValue = shares, SelectionMode = DataTooltip.SelectionMode, Points = pointsToHighlight.Select(x => new DataPointViewModel { Series = new Wpf.SeriesViewModel { Fill = ((Series.Series)x.SeriesView).Fill, Stroke = ((Series.Series)x.SeriesView).Stroke, StrokeThickness = ((Series.Series)x.SeriesView).StrokeThickness, Title = ((Series.Series)x.SeriesView).Title, }, ChartPoint = x }).ToList() }; DataTooltip.Visibility = Visibility.Visible; DataTooltip.UpdateLayout(); var location = GetTooltipPosition(senderPoint); DataTooltip.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(location.X, TimeSpan.FromMilliseconds(200))); DataTooltip.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(location.Y, TimeSpan.FromMilliseconds(200))); }
private void DataMouseEnter(object sender, EventArgs e) { var source = Model.ActualSeries.SelectMany(x => x.ActualValues.Points); var senderPoint = source.FirstOrDefault(x => x.View != null && Equals(((PointView)x.View).HoverShape, sender)); if (senderPoint == null) { return; } if (Hoverable) { senderPoint.View.OnHover(senderPoint); } if (DataTooltip != null) { TooltipTimeoutTimer.Stop(); if (DataTooltip.Parent == null) { Panel.SetZIndex(DataTooltip, int.MaxValue); AddToView(DataTooltip); Canvas.SetTop(DataTooltip, 0d); Canvas.SetLeft(DataTooltip, 0d); } if (DataTooltip.SelectionMode == null) { DataTooltip.SelectionMode = senderPoint.SeriesView.Model.PreferredSelectionMode; } var coreModel = ChartFunctions.GetTooltipData(senderPoint, Model, DataTooltip.SelectionMode.Value); DataTooltip.ViewModel = new WpfTooltipViewModel { XFormatter = coreModel.XFormatter, YFormatter = coreModel.YFormatter, SharedValue = coreModel.Shares, SelectionMode = DataTooltip.SelectionMode ?? TooltipSelectionMode.OnlySender, Points = coreModel.Points.Select(x => new DataPointViewModel { Series = new SeriesViewModel { Geometry = ((Series.Series)x.SeriesView).PointGeometry ?? Geometry.Parse("M 0,0.5 h 1,0.5 Z"), Fill = ((Series.Series)x.SeriesView).Fill, Stroke = ((Series.Series)x.SeriesView).Stroke, StrokeThickness = ((Series.Series)x.SeriesView).StrokeThickness, Title = ((Series.Series)x.SeriesView).Title, }, ChartPoint = x }).ToList() }; DataTooltip.Visibility = Visibility.Visible; DataTooltip.UpdateLayout(); var location = GetTooltipPosition(senderPoint); location = new Point(Canvas.GetLeft(DrawMargin) + location.X, Canvas.GetTop(DrawMargin) + location.Y); if (DisableAnimations) { Canvas.SetLeft(DataTooltip, location.X); Canvas.SetTop(DataTooltip, location.Y); } else { DataTooltip.BeginAnimation(Canvas.LeftProperty, new DoubleAnimation(location.X, TimeSpan.FromMilliseconds(200))); DataTooltip.BeginAnimation(Canvas.TopProperty, new DoubleAnimation(location.Y, TimeSpan.FromMilliseconds(200))); } } }