/// <summary> /// Updates the gridlines. /// </summary> /// <param name="axis">The Relevant Axis</param> /// <param name="linesRecycler">The Line Recycler</param> /// <param name="requiredLinescount">The Required Lines Count</param> /// <param name="isMajor">Check For Marjor Axis</param> /// <param name="checkOrginFlag">Check For Origin Flag</param> private static void UpdateGridlines(ChartAxis axis, UIElementsRecycler <Line> linesRecycler, int requiredLinescount, bool isMajor, bool checkOrginFlag) { if (linesRecycler == null || axis == null) { return; } foreach (var line in linesRecycler) { line.ClearValue(FrameworkElement.StyleProperty); } int totalLinesCount = requiredLinescount; if (axis.ShowOrigin && checkOrginFlag) { totalLinesCount += 1; } if (!linesRecycler.BindingProvider.Keys.Contains(FrameworkElement.StyleProperty)) { linesRecycler.BindingProvider.Add(FrameworkElement.StyleProperty, GetGridLineBinding(axis, isMajor)); } if (linesRecycler.Count > 0) { foreach (var line in linesRecycler) { line.SetBinding(FrameworkElement.StyleProperty, GetGridLineBinding(axis, isMajor)); } } linesRecycler.GenerateElements(totalLinesCount); var rangeStyles = axis.RangeStyles; if (rangeStyles != null && rangeStyles.Count > 0) { var values = !isMajor ? axis.SmallTickPoints : (from label in axis.VisibleLabels select label.Position).ToList(); for (int i = 0; i < values.Count; i++) { foreach (var chartAxisRangeStyle in rangeStyles) { var range = chartAxisRangeStyle.Range; var style = isMajor ? chartAxisRangeStyle.MajorGridLineStyle : chartAxisRangeStyle.MinorGridLineStyle; if (range.Start <= values[i] && range.End >= values[i] && style != null) { linesRecycler[i].SetBinding(FrameworkElement.StyleProperty, GetGridLineBinding(chartAxisRangeStyle, isMajor)); break; } } } } //StrokeDashArray applied only for the first line element when it is applied through style. //It is bug in the framework. //And hence manually setting stroke dash array for each and every grid line. ChartExtensionUtils.SetStrokeDashArray(linesRecycler); }
/// <summary> /// Called when [series mouse up]. /// </summary> /// <param name="source">The source.</param> /// <param name="position">The position.</param> protected internal override void OnSeriesMouseUp(object source, Point position) { var element = source as FrameworkElement; var segment = element != null ? element.Tag as ChartSegment : null; var newIndex = -1; if (this.ExplodeOnMouseClick && this.mouseUnderSegment == segment && this.allowExplode) { if (segment != null) { newIndex = (segment as PieSegment3D).Index; } else if (Adornments.Count > 0) { newIndex = ChartExtensionUtils.GetAdornmentIndex(source); } var oldIndex = ExplodeIndex; if (newIndex != oldIndex) { this.ExplodeIndex = newIndex; } else if (this.ExplodeIndex >= 0) { this.ExplodeIndex = -1; } this.allowExplode = false; } base.OnSeriesMouseUp(source, position); }
private static void CalculateNearestIndex(ref int minimum, ref int maximum, List <double> xValues, double startX, double endX) { minimum = ChartExtensionUtils.BinarySearch(xValues, startX, 0, maximum); maximum = ChartExtensionUtils.BinarySearch(xValues, endX, 0, maximum); minimum = startX <= xValues[minimum] ? minimum : minimum + 1; maximum = endX >= xValues[maximum] ? maximum : maximum - 1; }
private void SetScatterDraggingSegment(FrameworkElement frameworkElement, ref bool isAdornment) { // Empty point support only given for the interior case and not for symbol case. if (frameworkElement.Tag is EmptyPointSegment || frameworkElement.DataContext is EmptyPointSegment) { return; } if (frameworkElement.Tag is ScatterSegment || frameworkElement.DataContext is ScatterSegment) { draggingSegment = GetDraggingSegment(frameworkElement) as ScatterSegment; if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { SegmentIndex = ActualData.IndexOf(draggingSegment.Item); } else { SegmentIndex = Segments.IndexOf(draggingSegment); } } else { isAdornment = true; // Get the selected adornment index and select the adornment marker SegmentIndex = ChartExtensionUtils.GetAdornmentIndex(frameworkElement); if (SegmentIndex > -1) { draggingSegment = Segments[SegmentIndex] as ScatterSegment; } } }
internal override void UpdateTooltip(object originalSource) { if (ShowTooltip) { ChartDataPointInfo dataPoint = new ChartDataPointInfo(); int index = ChartExtensionUtils.GetAdornmentIndex(originalSource); if (index > -1) { dataPoint.Index = index; if (xValues.Count > index) { dataPoint.XData = xValues[index]; } if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed && GroupedSeriesYValues[0].Count > index) { dataPoint.YData = GroupedSeriesYValues[0][index]; } else if (YValues.Count > index) { dataPoint.YData = YValues[index]; } dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } UpdateSeriesTooltip(dataPoint); } } }
protected internal override void OnSeriesMouseUp(object source, Point position) { var element = source as FrameworkElement; var segment = element != null ? element.Tag as ChartSegment : null; int index = -1; if (ExplodeOnMouseClick && allowExplode && mouseUnderSegment == segment) { if (segment != null && segment.Series is AccumulationSeriesBase) { index = segment.Series is CircularSeriesBase && !double.IsNaN(((CircularSeriesBase)segment.Series).GroupTo) ? Segments.IndexOf(segment) : ActualData.IndexOf(segment.Item); } else if (Adornments.Count > 0) { index = ChartExtensionUtils.GetAdornmentIndex(source); } var newIndex = index; var oldIndex = ExplodeIndex; if (newIndex != oldIndex) { ExplodeIndex = newIndex; } else if (ExplodeIndex >= 0) { ExplodeIndex = -1; } allowExplode = false; } }
/// <summary> /// Method used to get the bool value for series or segment has dragging base. /// </summary> private bool IsDraggableSeries(ChartSeriesBase chartSeries) { if (ChartExtensionUtils.IsDraggable(chartSeries)) { ChangeSelectionCursor(false); return(true); } else { return(false); } }
protected override void OnPointerMoved(PointerRoutedEventArgs e) { if (ShowTooltip) { Canvas canvas = ActualArea.GetAdorningCanvas(); mousePos = e.GetCurrentPoint(canvas).Position; ChartDataPointInfo dataPoint = new ChartDataPointInfo(); int index = ChartExtensionUtils.GetAdornmentIndex(e.OriginalSource); if (index > -1) { if (ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed) { if (xValues.Count > index) { dataPoint.XData = GroupedXValuesIndexes[index]; } if (GroupedSeriesYValues[0].Count > index) { dataPoint.YData = GroupedSeriesYValues[0][index]; } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = GroupedActualData[index]; } } else { if (xValues.Count > index) { dataPoint.XData = xValues[index]; } if (YValues.Count > index) { dataPoint.YData = YValues[index]; } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } } UpdateSeriesTooltip(dataPoint); } } }
internal void UpdateTrackInterior(int segmentIndex) { if (parentSeries.TrackColor != null) { this.TrackColor = parentSeries.TrackColor; this.TrackOpacity = 1; } else { this.TrackColor = ChartExtensionUtils.GetInterior(parentSeries, segmentIndex); this.TrackOpacity = 0.2; } }
internal override void UpdateTooltip(object originalSource) { if (ShowTooltip) { FrameworkElement element = originalSource as FrameworkElement; object chartSegment = null; int index = -1; if (element != null) { if (element.Tag is ChartSegment) { chartSegment = element.Tag; } else if (Segments.Count > 0) { chartSegment = Segments[0]; } else { // WPF-28526- Tooltip not shown when set the single data point with adornments for continuous series. index = ChartExtensionUtils.GetAdornmentIndex(element); chartSegment = index != -1 ? new StackingAreaSegment() : null; } } if (chartSegment == null) { return; } SetTooltipDuration(); var canvas = this.Area.GetAdorningCanvas(); double xVal = 0; double yVal = 0; double stackedYValue = double.NaN; object data = null; index = 0; if (this.Area.SeriesClipRect.Contains(mousePos)) { var point = new Point( mousePos.X - this.Area.SeriesClipRect.Left, mousePos.Y - this.Area.SeriesClipRect.Top); this.FindNearestChartPoint(point, out xVal, out yVal, out stackedYValue); if (double.IsNaN(xVal)) { return; } if (ActualXAxis is CategoryAxis && (ActualXAxis as CategoryAxis).IsIndexed) { index = YValues.IndexOf(yVal); } else { index = this.GetXValues().IndexOf(xVal); } foreach (var series in Area.Series) { if (series == this) { data = this.ActualData[index]; } } } if (data == null) { return; // To ignore tooltip when mousePos is not inside the SeriesClipRect. } if (this.Area.Tooltip == null) { this.Area.Tooltip = new ChartTooltip(); } var chartTooltip = this.Area.Tooltip as ChartTooltip; var stackingAreaSegment = chartSegment as StackingAreaSegment; stackingAreaSegment.Item = data; stackingAreaSegment.XData = xVal; stackingAreaSegment.YData = yVal; if (chartTooltip != null) { if (canvas.Children.Count == 0 || (canvas.Children.Count > 0 && !IsTooltipAvailable(canvas))) { chartTooltip.Content = chartSegment; if (chartTooltip.Content == null) { return; } 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; } } chartTooltip.Content = chartSegment; if (chartTooltip.Content == null) { RemoveTooltip(); return; } 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 { _stopwatch.Restart(); 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 } } } }
private object CalculateDateTimeIntervalType(DoubleRange actualRange, Size availableSize, ref DateTimeIntervalType dateTimeIntervalType) { var dateTimeMin = ChartExtensionUtils.FromOADate(actualRange.Start); var dateTimeMax = ChartExtensionUtils.FromOADate(actualRange.End); var timeSpan = dateTimeMax.Subtract(dateTimeMin); double interval = 0; switch (dateTimeIntervalType) { case DateTimeIntervalType.Years: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 365), availableSize); break; case DateTimeIntervalType.Months: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 30), availableSize); break; case DateTimeIntervalType.Days: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays), availableSize); break; case DateTimeIntervalType.Hours: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalHours), availableSize); break; case DateTimeIntervalType.Minutes: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMinutes), availableSize); break; case DateTimeIntervalType.Seconds: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalSeconds), availableSize); break; case DateTimeIntervalType.Milliseconds: interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMilliseconds), availableSize); break; case DateTimeIntervalType.Auto: var range = new DoubleRange(0, timeSpan.TotalDays / 365); interval = base.CalculateNiceInterval(range, availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Years; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays / 30), availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Months; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalDays), availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Days; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalHours), availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Hours; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMinutes), availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Minutes; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalSeconds), availableSize); if (interval >= 1) { dateTimeIntervalType = DateTimeIntervalType.Seconds; return(interval); } interval = base.CalculateNiceInterval(new DoubleRange(0, timeSpan.TotalMilliseconds), availableSize); dateTimeIntervalType = DateTimeIntervalType.Milliseconds; break; } return(interval); }
/// <summary> /// Modifies the source data before passing it to the target for display in the UI. /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="language"></param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter, string language) { int index = int.Parse(parameter.ToString()); return(ChartExtensionUtils.GetInterior(series, index)); }
protected override void OnPointerMoved(PointerRoutedEventArgs e) { if (ShowTooltip) { Canvas canvas = ActualArea.GetAdorningCanvas(); mousePos = e.GetCurrentPoint(canvas).Position; ChartDataPointInfo dataPoint = new ChartDataPointInfo(); int index = ChartExtensionUtils.GetAdornmentIndex(e.OriginalSource); if (index > -1) { if ((ActualXAxis is CategoryAxis) && (!(ActualXAxis as CategoryAxis).IsIndexed)) { if (GroupedSeriesYValues[0].Count > index) { dataPoint.High = GroupedSeriesYValues[0][index]; } if (GroupedSeriesYValues[1].Count > index) { dataPoint.Low = GroupedSeriesYValues[1][index]; } if (GroupedSeriesYValues[2].Count > index) { dataPoint.Open = GroupedSeriesYValues[2][index]; } if (GroupedSeriesYValues[3].Count > index) { dataPoint.Close = GroupedSeriesYValues[3][index]; } } else { if (ActualSeriesYValues[0].Count > index) { dataPoint.High = ActualSeriesYValues[0][index]; } if (ActualSeriesYValues[1].Count > index) { dataPoint.Low = ActualSeriesYValues[1][index]; } if (ActualSeriesYValues[2].Count > index) { dataPoint.Open = ActualSeriesYValues[2][index]; } if (ActualSeriesYValues[3].Count > index) { dataPoint.Close = ActualSeriesYValues[3][index]; } } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } UpdateSeriesTooltip(dataPoint); } } }
protected internal override void OnPointerMoved(PointerRoutedEventArgs e) { if (ChartArea == null) { return; } if (this.EnableSegmentSelection || this.EnableSeriesSelection) { FrameworkElement element = e.OriginalSource as FrameworkElement; ChartSegment segment = null; if (element != null) { if (element.Tag != null) { segment = element.Tag as ChartSegment; } } if (segment is TrendlineSegment) { return; } if (element.DataContext is LegendItem) { return; } #if __IOS__ || __ANDROID__ var image = (element as Border)?.Child as Image; #else var image = element as Image; #endif if (segment != null && segment.Series is ISegmentSelectable && !(segment.Item is Trendline)) { // Scatter series supports selection and dragging at the same time. if (!(segment.Series is ScatterSeries) && IsDraggableSeries(segment.Series)) { return; } if (!segment.Series.IsLinear || EnableSeriesSelection) { ChangeSelectionCursor(true); } else { ChangeSelectionCursor(false); } if (SelectionMode == Charts.SelectionMode.MouseMove) { if (!segment.Series.IsSideBySide && segment.Series is CartesianSeries && !(segment.Series is ScatterSeries) && !(segment.Series is BubbleSeries)) { Point canvasPoint = e.GetCurrentPoint(segment.Series.ActualArea.GetAdorningCanvas()).Position; ChartDataPointInfo data = (segment.Series as ChartSeries).GetDataPoint(canvasPoint); OnMouseMoveSelection(segment.Series, data); } else { int segIndex = segment.Series is CircularSeriesBase && !double.IsNaN(((CircularSeriesBase)segment.Series).GroupTo) ?segment.Series.Segments.IndexOf(segment): segment.Series.ActualData.IndexOf(segment.Item); OnMouseMoveSelection(segment.Series, segIndex); } } } else if (e.OriginalSource is Shape && (e.OriginalSource as Shape).DataContext is ChartAdornmentContainer && ((e.OriginalSource as Shape).DataContext as ChartAdornmentContainer).Tag is int) { // Check the selected element is adornment shape selectedAdornmentPresenter = VisualTreeHelper.GetParent((e.OriginalSource as Shape).DataContext as ChartAdornmentContainer) as ChartAdornmentPresenter; if (IsDraggableSeries(selectedAdornmentPresenter.Series)) { return; } ChangeSelectionCursor(true); if (SelectionMode == Charts.SelectionMode.MouseMove) { index = (int)((e.OriginalSource as Shape).DataContext as ChartAdornmentContainer).Tag; if (selectedAdornmentPresenter != null && selectedAdornmentPresenter.Series is ISegmentSelectable) { OnMouseMoveSelection(selectedAdornmentPresenter.Series, index); } } } else if (image != null && image.Source is WriteableBitmap) { GetBitmapSeriesCollection(element, e); // Bitmap segment selection process handling. if (SelectionMode == Charts.SelectionMode.MouseMove) { OnBitmapSeriesMouseMoveSelection(element, e); } } else if (element is Border || element is TextBlock || element is Shape) // check the selected element is adornment label { ChangeSelectionCursor(false); FrameworkElement frameworkElement = e.OriginalSource as FrameworkElement; int count = e.OriginalSource is TextBlock ? 3 : 2; for (int i = 0; i < count; i++) { if (frameworkElement != null) { frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; } else { break; } } if (frameworkElement is ContentPresenter) { index = ChartExtensionUtils.GetAdornmentIndex(frameworkElement); if (index != -1) { ChangeSelectionCursor(true); } if (SelectionMode == Charts.SelectionMode.MouseMove) { frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; if (frameworkElement is ChartAdornmentPresenter || frameworkElement is ChartAdornmentContainer) { while (!(frameworkElement is ChartAdornmentPresenter) && frameworkElement != null) { frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; } selectedAdornmentPresenter = frameworkElement as ChartAdornmentPresenter; if (IsDraggableSeries(selectedAdornmentPresenter.Series)) { return; } if (selectedAdornmentPresenter != null && selectedAdornmentPresenter.Series is ISegmentSelectable) { OnMouseMoveSelection(selectedAdornmentPresenter.Series, index); } } } } var contentControl = frameworkElement as ContentControl; if (contentControl != null && contentControl.Tag is int) { ChangeSelectionCursor(true); if (SelectionMode == Charts.SelectionMode.MouseMove) { index = (int)contentControl.Tag; frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; var chartAdornmentPresenter = frameworkElement as ChartAdornmentPresenter; if (chartAdornmentPresenter != null) { selectedAdornmentPresenter = chartAdornmentPresenter; if (IsDraggableSeries(selectedAdornmentPresenter.Series)) { return; } if (selectedAdornmentPresenter != null && selectedAdornmentPresenter.Series is ISegmentSelectable) { OnMouseMoveSelection(selectedAdornmentPresenter.Series, index); } } } } } else if (ChartArea.PreviousSelectedSeries != null && ChartArea.CurrentSelectedSeries != null && SelectionMode == Charts.SelectionMode.MouseMove && ChartArea.VisibleSeries.Contains(ChartArea.PreviousSelectedSeries)) { ChangeSelectionCursor(false); bool isCancel; if (EnableSeriesSelection) { isCancel = ChartArea.CurrentSelectedSeries.RaiseSelectionChanging(-1, ChartArea.SeriesSelectedIndex); } else { isCancel = ChartArea.CurrentSelectedSeries.RaiseSelectionChanging( -1, (ChartArea.CurrentSelectedSeries as ISegmentSelectable).SelectedIndex); } if (!isCancel) { Deselect(); } } else { ChangeSelectionCursor(false); } } else { ChangeSelectionCursor(false); } }
/// <summary> /// Called when Pointer Released in Chart /// </summary> /// <param name="e"></param> protected internal override void OnPointerReleased(PointerRoutedEventArgs e) { if (ChartArea == null) { return; } if (SelectionMode == Charts.SelectionMode.MouseClick) { FrameworkElement element = e.OriginalSource as FrameworkElement; ChartSegment segment = null; ChartArea.CurrentSelectedSeries = null; if (element != null) { if (element.Tag != null) { segment = element.Tag as ChartSegment; } } if (segment is TrendlineSegment) { return; } #if __IOS__ || __ANDROID__ var image = (element as Border)?.Child as Image; #else var image = element as Image; #endif if (image != null && image.Source is WriteableBitmap) { // Bitmap segment selection process handling. OnBitmapSeriesMouseDownSelection(element, e); } else if (segment != null && segment == mouseUnderSegment && segment.Series is ISegmentSelectable && !(segment.Item is Trendline)) { if (!segment.Series.IsSideBySide && segment.Series is CartesianSeries && !(segment.Series is ScatterSeries) && !(segment.Series is BubbleSeries)) { Point canvasPoint = e.GetCurrentPoint(segment.Series.ActualArea.GetAdorningCanvas()).Position; ChartDataPointInfo data = (segment.Series as ChartSeries).GetDataPoint(canvasPoint); OnMouseDownSelection(segment.Series, data); } else { int index = -1; if ((segment.Series.ActualXAxis is CategoryAxis) && !(segment.Series.ActualXAxis as CategoryAxis).IsIndexed && segment.Series.IsSideBySide && !(segment.Series is FinancialSeriesBase) && (!(segment.Series is RangeSeriesBase)) && !(segment.Series is WaterfallSeries)) { index = segment.Series.GroupedActualData.IndexOf(segment.Item); } else { index = segment.Series is CircularSeriesBase && !double.IsNaN(((CircularSeriesBase)segment.Series).GroupTo)? segment.Series.Segments.IndexOf(segment): segment.Series.ActualData.IndexOf(segment.Item); } OnMouseDownSelection(segment.Series, index); } } else { // Get the selected adornment index and select the adornment marker index = ChartExtensionUtils.GetAdornmentIndex(element); FrameworkElement frameworkElement = e.OriginalSource as FrameworkElement; var chartAdornmentPresenter = frameworkElement as ChartAdornmentPresenter; while (frameworkElement != null && chartAdornmentPresenter == null) { frameworkElement = VisualTreeHelper.GetParent(frameworkElement) as FrameworkElement; chartAdornmentPresenter = frameworkElement as ChartAdornmentPresenter; } if (chartAdornmentPresenter != null && chartAdornmentPresenter.Series is ISegmentSelectable) { OnMouseDownSelection(chartAdornmentPresenter.Series, index); } } if (selectedAdornmentPresenter != null) { selectedAdornmentPresenter = null; } } AdorningCanvas.ReleasePointerCapture(e.Pointer); }
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 } } } }