private void SetTooltipSegmentItem(StepLineSegment lineSegment) { double xVal = 0; double yVal = 0; double stackValue = double.NaN; var point = new Point(mousePos.X - this.Area.SeriesClipRect.Left, mousePos.Y - this.Area.SeriesClipRect.Top); FindNearestChartPoint(point, out xVal, out yVal, out stackValue); if (double.IsNaN(xVal)) { return; } if (lineSegment != null) { lineSegment.YData = yVal == lineSegment.Y1Value ? lineSegment.Y1Value : lineSegment.Y1Data; } var segmentIndex = this.GetXValues().IndexOf(xVal); if (!IsIndexed) { IList <double> xValues = this.ActualXValues as IList <double>; int i = segmentIndex; double nearestY = this.ActualSeriesYValues[0][i]; while (xValues.Count > i && xValues[i] == xVal) { double yValue = ActualArea.PointToValue(ActualYAxis, point); var validateYValue = ActualSeriesYValues[0][i]; if (Math.Abs(yValue - validateYValue) <= Math.Abs(yValue - nearestY)) { segmentIndex = i; nearestY = validateYValue; } i++; } } lineSegment.Item = this.ActualData[segmentIndex]; }
internal override void UpdateTooltip(object originalSource) { if (ShowTooltip) { FrameworkElement element = originalSource as FrameworkElement; object chartSegment = null; if (element != null) { if (element.Tag is ChartSegment) { chartSegment = element.Tag; } else if (element.DataContext is ChartSegment && !(element.DataContext is ChartAdornment)) { chartSegment = element.DataContext; } else { int index = ChartExtensionUtils.GetAdornmentIndex(element); if (index != -1) { if (index < Segments.Count) { chartSegment = Segments[index]; } else if (Segments.Count > 0) { chartSegment = Segments[index - 1]; } else if (index < Adornments.Count) { // WPF-28526- Tooltip not shown when set the single data point with adornments for continuous series. ChartAdornment adornment = Adornments[index]; chartSegment = new StepLineSegment() { X1Value = adornment.XData, Y1Value = adornment.YData, X1Data = adornment.XData, Y1Data = adornment.YData, X1 = adornment.XData, Y1 = adornment.YData, XData = adornment.XData, YData = adornment.YData, Item = adornment.Item }; } } } } if (chartSegment == null) { return; } SetTooltipDuration(); var canvas = this.Area.GetAdorningCanvas(); if (this.Area.Tooltip == null) { this.Area.Tooltip = new ChartTooltip(); } var chartTooltip = this.Area.Tooltip as ChartTooltip; if (chartTooltip != null) { var lineSegment = chartSegment as StepLineSegment; if (canvas.Children.Count == 0 || (canvas.Children.Count > 0 && !IsTooltipAvailable(canvas))) { SetTooltipSegmentItem(lineSegment); chartTooltip.Content = chartSegment; if (ChartTooltip.GetInitialShowDelay(this) == 0) { canvas.Children.Add(chartTooltip); } chartTooltip.ContentTemplate = this.GetTooltipTemplate(); AddTooltip(); if (ChartTooltip.GetEnableAnimation(this)) { SetDoubleAnimation(chartTooltip); storyBoard.Children.Add(leftDoubleAnimation); storyBoard.Children.Add(topDoubleAnimation); Canvas.SetLeft(chartTooltip, chartTooltip.LeftOffset); Canvas.SetTop(chartTooltip, chartTooltip.TopOffset); _stopwatch.Start(); } else { Canvas.SetLeft(chartTooltip, chartTooltip.LeftOffset); Canvas.SetTop(chartTooltip, chartTooltip.TopOffset); _stopwatch.Start(); } } else { foreach (var child in canvas.Children) { var tooltip = child as ChartTooltip; if (tooltip != null) { chartTooltip = tooltip; } } SetTooltipSegmentItem(lineSegment); chartTooltip.Content = chartSegment; chartTooltip.ContentTemplate = this.GetTooltipTemplate(); AddTooltip(); #if NETFX_CORE if (_stopwatch.ElapsedMilliseconds > 100) { #endif if (ChartTooltip.GetEnableAnimation(this)) { _stopwatch.Restart(); if (leftDoubleAnimation == null || topDoubleAnimation == null || storyBoard == null) { SetDoubleAnimation(chartTooltip); } else { leftDoubleAnimation.To = chartTooltip.LeftOffset; topDoubleAnimation.To = chartTooltip.TopOffset; storyBoard.Begin(); } } else { Canvas.SetLeft(chartTooltip, chartTooltip.LeftOffset); Canvas.SetTop(chartTooltip, chartTooltip.TopOffset); } #if NETFX_CORE } else if (EnableAnimation == false) { Canvas.SetLeft(chartTooltip, chartTooltip.LeftOffset); Canvas.SetTop(chartTooltip, chartTooltip.TopOffset); } #endif } } } }
/// <summary> /// Creates the segments of StepLineSeries. /// </summary> public override void CreateSegments() { List <double> xValues = null; bool isGrouping = this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed; if (isGrouping) { xValues = GroupedXValuesIndexes; } else { xValues = GetXValues(); } if (xValues == null) { return; } double xOffset = 0d; if (ActualXAxis is CategoryAxis && (ActualXAxis as CategoryAxis).LabelPlacement == LabelPlacement.BetweenTicks) { xOffset = 0.5d; } if (isGrouping) { Segments.Clear(); Adornments.Clear(); for (int i = 0; i < xValues.Count; i++) { int index = i + 1; ChartPoint point1, point2, stepPoint; if (AdornmentsInfo != null) { Adornments.Add(this.CreateAdornment(this, xValues[i], GroupedSeriesYValues[0][i], xValues[i], GroupedSeriesYValues[0][i])); Adornments[i].Item = ActualData[i]; } if (index < xValues.Count) { point1 = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]); point2 = new ChartPoint(xValues[index] - xOffset, GroupedSeriesYValues[0][i]); stepPoint = new ChartPoint(xValues[index] - xOffset, GroupedSeriesYValues[0][index]); } else { if (!(xOffset > 0)) { continue; } point1 = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]); point2 = new ChartPoint(xValues[i] + xOffset, GroupedSeriesYValues[0][i]); stepPoint = new ChartPoint(xValues[i] - xOffset, GroupedSeriesYValues[0][i]); } var segment = new StepLineSegment(point1, stepPoint, point2, this) { Item = ActualData[i] }; segment.Series = this; List <ChartPoint> listPoints = new List <ChartPoint>(); listPoints.Add(point1); listPoints.Add(stepPoint); listPoints.Add(point2); segment.SetData(listPoints); Segments.Add(segment); listPoints = null; } } else { ClearUnUsedStepLineSegment(DataCount); ClearUnUsedAdornments(DataCount); for (int i = 0; i < DataCount; i++) { int index = i + 1; ChartPoint point1, point2, stepPoint; if (AdornmentsInfo != null) { if (i < Adornments.Count) { Adornments[i].SetData(xValues[i], YValues[i], xValues[i], YValues[i]); Adornments[i].Item = ActualData[i]; } else { Adornments.Add(this.CreateAdornment(this, xValues[i], YValues[i], xValues[i], YValues[i])); Adornments[i].Item = ActualData[i]; } } if (index < DataCount) { point1 = new ChartPoint(xValues[i] - xOffset, YValues[i]); point2 = new ChartPoint(xValues[index] - xOffset, YValues[i]); stepPoint = new ChartPoint(xValues[index] - xOffset, YValues[index]); } else { if (!(xOffset > 0)) { continue; } point1 = new ChartPoint(xValues[i] - xOffset, YValues[i]); point2 = new ChartPoint(xValues[i] + xOffset, YValues[i]); stepPoint = new ChartPoint(xValues[i] - xOffset, YValues[i]); } if (i < Segments.Count) { Segments[i].SetData(new List <ChartPoint> { point1, stepPoint, point2 }); Segments[i].Item = ActualData[i]; (Segments[i] as StepLineSegment).YData = YValues[i]; if (SegmentColorPath != null && !Segments[i].IsEmptySegmentInterior && ColorValues.Count > 0 && !Segments[i].IsSelectedSegment) { Segments[i].Interior = (Interior != null) ? Interior : ColorValues[i]; } } else { var segment = new StepLineSegment(point1, stepPoint, point2, this) { Item = ActualData[i] }; segment.Series = this; List <ChartPoint> listPoints = new List <ChartPoint>(); listPoints.Add(point1); listPoints.Add(stepPoint); listPoints.Add(point2); segment.SetData(listPoints); Segments.Add(segment); listPoints = null; } } } if (ShowEmptyPoints) { UpdateEmptyPointSegments(xValues, false); } }