/// <summary> /// This method used to get the chart data at a mouse position. /// </summary> /// <param name="mousePos"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(Point mousePos) { double xVal = 0; double yVal = 0; double stackedYValue = double.NaN; dataPoint = null; dataPoint = new ChartDataPointInfo(); 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); dataPoint.XData = xVal; int index = this.GetXValues().IndexOf(xVal); if (index > -1) { dataPoint.High = ActualSeriesYValues[0][index]; dataPoint.Low = ActualSeriesYValues[1][index]; dataPoint.Index = index; dataPoint.Series = this; if (index > -1 && ActualData.Count > index) { dataPoint.Item = ActualData[index]; } } } return(dataPoint); }
/// <summary> /// This method used to get the chart data at an index. /// </summary> /// <param name="index"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(int index) { IList <double> xValues = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues(); dataPoint = null; if (index < xValues.Count) { dataPoint = new ChartDataPointInfo(); if (xValues.Count > index) { dataPoint.XData = IsIndexed ? index : xValues[index]; } if (YValues.Count > index) { dataPoint.YData = YValues[index]; } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } } return(dataPoint); }
/// <summary> /// This method used to get the chart data index at an SfChart co-ordinates /// </summary> /// <param name="index"></param> /// <returns></returns> internal override int GetDataPointIndex(Point point) { Canvas canvas = Area.GetAdorningCanvas(); double left = Area.ActualWidth - canvas.ActualWidth; double top = Area.ActualHeight - canvas.ActualHeight; ChartDataPointInfo data = null; point.X = point.X - left + Area.Margin.Left; point.Y = point.Y - top + Area.Margin.Top; Point mousePos = new Point(point.X - Area.SeriesClipRect.Left, point.Y - Area.SeriesClipRect.Top); double currentBitmapPixel = (Area.fastRenderSurface.PixelWidth * (int)mousePos.Y + (int)mousePos.X); if (!Area.isBitmapPixelsConverted) { Area.ConvertBitmapPixels(); } if (Pixels.Contains((int)currentBitmapPixel)) { data = GetDataPoint(point); } if (data != null) { return(data.Index); } else { return(-1); } }
/// <summary> /// This method used to get the chart data at an index. /// </summary> /// <param name="index"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(int index) { IList <double> xValues = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues(); dataPoint = null; dataPoint = new ChartDataPointInfo(); if (xValues.Count > index) { dataPoint.XData = IsIndexed ? index : xValues[index]; } if (ActualSeriesYValues != null && ActualSeriesYValues.Count() > 0) { if (ActualSeriesYValues[0].Count > index) { dataPoint.High = ActualSeriesYValues[0][index]; } if (ActualSeriesYValues[1].Count > index) { dataPoint.Low = ActualSeriesYValues[1][index]; } } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } return(dataPoint); }
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); } } }
/// <summary> /// Method used to return the hittest series while mouse action. /// </summary> /// <returns></returns> internal override bool IsHitTestSeries() { // Gets the current mouse position chart data point ChartDataPointInfo datapoint = GetDataPoint(Area.adorningCanvasPoint); if (datapoint != null) { return(true); } 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); } } }
protected override void OnPointerMoved(PointerRoutedEventArgs e) { if (ShowTooltip && e.OriginalSource is Polyline) { Canvas canvas = ActualArea.GetAdorningCanvas(); mousePos = e.GetCurrentPoint(canvas).Position; ChartDataPointInfo dataPointInfo = GetCurveDataPoint(mousePos, (e.OriginalSource as Polyline).Tag); UpdateSeriesTooltip(dataPointInfo); } else { base.OnPointerMoved(e); } }
/// <summary> /// This method used to gets the chart data point at a position. /// </summary> /// <param name="mousePos">The mouse position.</param> /// <returns>Returns the data point nearest to the mouse position.</returns> internal override ChartDataPointInfo GetDataPoint(Point mousePos) { Rect rect; int startIndex, endIndex; List <int> hitIndexes = new List <int>(); IList <double> xValues = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues(); CalculateHittestRect(mousePos, out startIndex, out endIndex, out rect); Point y1Value = new Point(); Point y2Value = new Point(); for (int i = startIndex; i <= endIndex; i++) { y1Value.X = IsIndexed ? i : xValues[i]; y1Value.Y = ActualSeriesYValues[0][i]; y2Value.X = IsIndexed ? i : xValues[i]; y2Value.Y = ActualSeriesYValues[1][i]; if (rect.Contains(y1Value) || rect.Contains(y2Value)) { hitIndexes.Add(i); } } if (hitIndexes.Count > 0) { int i = hitIndexes[hitIndexes.Count / 2]; hitIndexes = null; dataPoint = new ChartDataPointInfo(); dataPoint.Index = i; dataPoint.XData = xValues[i]; dataPoint.High = ActualSeriesYValues[0][i]; dataPoint.Low = ActualSeriesYValues[1][i]; dataPoint.Series = this; if (i > -1 && ActualData.Count > i) { dataPoint.Item = ActualData[i]; } return(dataPoint); } else { return(dataPoint); } }
/// <summary> /// Method used to select bitmap series in mouse down /// </summary> /// <param name="element"></param> /// <param name="e"></param> private void OnBitmapSeriesMouseDownSelection(FrameworkElement element, PointerRoutedEventArgs e) { Point canvasPoint = e.GetCurrentPoint(ChartArea.GetAdorningCanvas()).Position; if (seriesCollection.Count > 0) { ChartArea.CurrentSelectedSeries = seriesCollection[seriesCollection.Count - 1]; if (ChartArea.CurrentSelectedSeries is ISegmentSelectable) { ChartDataPointInfo data = ChartArea.CurrentSelectedSeries.GetDataPoint(canvasPoint); OnMouseDownSelection(ChartArea.CurrentSelectedSeries, data); } } }
private ChartDataPointInfo GetCurveDataPoint(Point mousePos, object tag) { hitPoint.X = mousePos.X - this.Area.SeriesClipRect.Left; hitPoint.Y = mousePos.Y - this.Area.SeriesClipRect.Top; // Calculate the bounds region from the area width & height double x = Math.Floor(Area.SeriesClipRect.Width * 0.025); double y = Math.Floor(Area.SeriesClipRect.Height * 0.025); hitPoint.X = hitPoint.X - x; hitPoint.Y = hitPoint.Y - y; startPoint.X = ActualArea.PointToValue(ActualXAxis, hitPoint); startPoint.Y = ActualArea.PointToValue(ActualYAxis, hitPoint); hitPoint.X = hitPoint.X + (2 * x); hitPoint.Y = hitPoint.Y + (2 * y); endPoint.X = ActualArea.PointToValue(ActualXAxis, hitPoint); endPoint.Y = ActualArea.PointToValue(ActualYAxis, hitPoint); Rect rect = new Rect(startPoint, endPoint); dataPoint = null; PointCollection distributionPoints = (tag as HistogramDistributionSegment).distributionPoints; for (int i = 0; i < distributionPoints.Count; i++) { hitPoint.X = distributionPoints[i].X; hitPoint.Y = distributionPoints[i].Y; if (rect.Contains(hitPoint)) { dataPoint = new ChartDataPointInfo(); dataPoint.Index = i; dataPoint.XData = distributionPoints[i].X; dataPoint.YData = distributionPoints[i].Y; dataPoint.Series = this; if (i > -1 && ActualData.Count > i) { dataPoint.Item = ActualData[i]; } break; } } return(dataPoint); }
/// <summary> /// This method used to get the chart data index at an SfChart co-ordinates /// </summary> /// <param name="index"></param> /// <returns></returns> internal virtual int GetDataPointIndex(Point point) { Canvas canvas = Area.GetAdorningCanvas(); double left = Area.ActualWidth - canvas.ActualWidth; double top = Area.ActualHeight - canvas.ActualHeight; ChartDataPointInfo data = null; point.X = point.X - left + Area.Margin.Left; point.Y = point.Y - top + Area.Margin.Top; data = GetDataPoint(point); if (data != null) { return(data.Index); } else { return(-1); } }
/// <summary> /// This method used to gets the chart data point at a position. /// </summary> /// <param name="mousePos"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(Point mousePos) { Rect rect; int startIndex, endIndex; List <int> hitIndexes = new List <int>(); CalculateHittestRect(mousePos, out startIndex, out endIndex, out rect); for (int i = startIndex; i <= endIndex; i++) { hitPoint.X = IsIndexed ? i : xValues[i]; hitPoint.Y = YValues[i]; if (rect.Contains(hitPoint)) { hitIndexes.Add(i); } } if (hitIndexes.Count > 0) { int i = hitIndexes[hitIndexes.Count / 2]; hitIndexes = null; dataPoint = new ChartDataPointInfo(); dataPoint.Index = i; dataPoint.XData = xValues[i]; dataPoint.YData = YValues[i]; dataPoint.Series = this; if (i > -1 && ActualData.Count > i) { dataPoint.Item = ActualData[i]; } return(dataPoint); } else { return(dataPoint); } }
/// <summary> /// Method used to select bitmap series in mouse move /// </summary> /// <param name="element"></param> /// <param name="e"></param> private void OnBitmapSeriesMouseMoveSelection(FrameworkElement element, PointerRoutedEventArgs e) { Point canvasPoint = e.GetCurrentPoint(ChartArea.GetAdorningCanvas()).Position; if (seriesCollection.Count > 0) { ChartArea.CurrentSelectedSeries = seriesCollection[seriesCollection.Count - 1]; if (IsDraggableSeries(ChartArea.CurrentSelectedSeries)) { return; } if (ChartArea.CurrentSelectedSeries is ISegmentSelectable) { ChartDataPointInfo data = ChartArea.CurrentSelectedSeries.GetDataPoint(canvasPoint); OnMouseMoveSelection(ChartArea.CurrentSelectedSeries, data); } } else if (ChartArea.PreviousSelectedSeries != null && ChartArea.VisibleSeries.Contains(ChartArea.PreviousSelectedSeries)) { 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(); } } }
/// <summary> /// This method used to get the chart data at an index. /// </summary> /// <param name="index"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(int index) { if (this.ActualXAxis is CategoryAxis && !(this.ActualXAxis as CategoryAxis).IsIndexed) { IList <double> xValues = GroupedXValuesIndexes; dataPoint = null; if (index >= 0 && index < xValues.Count) { dataPoint = new ChartDataPointInfo(); if (xValues.Count > index) { dataPoint.XData = xValues[index]; } dataPoint.Index = index; dataPoint.Series = this; if (this is ColumnSeries || this is FastColumnBitmapSeries || this is FastStackingColumnBitmapSeries || this is StackingColumnSeries) { if (GroupedSeriesYValues[0].Count > index) { dataPoint.YData = GroupedSeriesYValues[0][index]; } if (GroupedActualData.Count > index) { dataPoint.Item = GroupedActualData[index]; } } else { if (YValues.Count > index) { dataPoint.YData = YValues[index]; } if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } } } return(dataPoint); } else { IList <double> xValues = GetXValues(); dataPoint = null; if (index >= 0 && index < xValues.Count) { dataPoint = new ChartDataPointInfo(); if (xValues.Count > index) { dataPoint.XData = IsIndexed ? index : xValues[index]; } if (YValues.Count > index) { dataPoint.YData = YValues[index]; } dataPoint.Index = index; dataPoint.Series = this; if (ActualData.Count > index) { dataPoint.Item = ActualData[index]; } } return(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); } }
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); } } }
internal override void SelectedSegmentsIndexes_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { ChartSelectionChangedEventArgs chartSelectionChangedEventArgs; ChartSegment prevSelectedSegment = null; if (prevDataPoint != null && Segments.Count > 0) { prevSelectedSegment = (from segment in Segments where segment is FastLineSegment && (segment as FastLineSegment).xChartVals.Contains(prevDataPoint.XData) select segment).FirstOrDefault() as ChartSegment; } switch (e.Action) { case NotifyCollectionChangedAction.Add: if (e.NewItems != null && !(ActualArea.SelectionBehaviour.SelectionStyle == SelectionStyle.Single)) { int oldIndex = PreviousSelectedIndex; int newIndex = (int)e.NewItems[0]; // For adornment selection implementation if (newIndex >= 0 && ActualArea.GetEnableSegmentSelection()) { // Selects the adornment when the mouse is over or clicked on adornments(adornment selection). if (adornmentInfo != null && adornmentInfo.HighlightOnSelection) { UpdateAdornmentSelection(newIndex); } if (ActualArea != null && Segments.Count > 0) { var selectedSegment = (from segment in Segments where segment is FastLineSegment && (segment as FastLineSegment).xChartVals.Contains(dataPoint.XData) select segment).FirstOrDefault(); if (selectedSegment != null) { chartSelectionChangedEventArgs = new ChartSelectionChangedEventArgs() { SelectedSegment = selectedSegment, SelectedSegments = Area.SelectedSegments, SelectedSeries = this, SelectedIndex = newIndex, PreviousSelectedIndex = oldIndex, NewPointInfo = GetDataPoint(newIndex), IsSelected = true }; chartSelectionChangedEventArgs.PreviousSelectedSeries = this.ActualArea.PreviousSelectedSeries; if (oldIndex != -1) { chartSelectionChangedEventArgs.PreviousSelectedSegment = prevSelectedSegment; chartSelectionChangedEventArgs.OldPointInfo = GetDataPoint(oldIndex); } (ActualArea as SfChart).OnSelectionChanged(chartSelectionChangedEventArgs); PreviousSelectedIndex = newIndex; prevDataPoint = dataPoint; } } else if (Segments.Count == 0) { triggerSelectionChangedEventOnLoad = true; } } } break; case NotifyCollectionChangedAction.Remove: if (e.OldItems != null && !(ActualArea.SelectionBehaviour.SelectionStyle == SelectionStyle.Single)) { int newIndex = (int)e.OldItems[0]; chartSelectionChangedEventArgs = new ChartSelectionChangedEventArgs() { SelectedSegment = null, SelectedSegments = Area.SelectedSegments, SelectedSeries = null, SelectedIndex = newIndex, PreviousSelectedIndex = PreviousSelectedIndex, NewPointInfo = null, OldPointInfo = GetDataPoint(PreviousSelectedIndex), PreviousSelectedSeries = this, IsSelected = false }; if (PreviousSelectedIndex != -1) { chartSelectionChangedEventArgs.PreviousSelectedSegment = prevSelectedSegment; } (ActualArea as SfChart).OnSelectionChanged(chartSelectionChangedEventArgs); OnResetSegment(newIndex); PreviousSelectedIndex = newIndex; } break; } }
/// <summary> /// This method used to gets the chart data point at a position. /// </summary> /// <param name="mousePos"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(Point mousePos) { bool isGrouped = ActualXAxis is CategoryAxis && !(ActualXAxis as CategoryAxis).IsIndexed; if (isGrouped) { xValues = GroupedXValuesIndexes; } else { xValues = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues(); } hitPoint.X = mousePos.X - this.Area.SeriesClipRect.Left; hitPoint.Y = mousePos.Y - this.Area.SeriesClipRect.Top; hitPoint.X = hitPoint.X - ScatterWidth; hitPoint.Y = hitPoint.Y - ScatterHeight; startPoint.X = ActualArea.PointToValue(ActualXAxis, hitPoint); startPoint.Y = ActualArea.PointToValue(ActualYAxis, hitPoint); hitPoint.X = hitPoint.X + (2 * ScatterWidth); hitPoint.Y = hitPoint.Y + (2 * ScatterHeight); endPoint.X = ActualArea.PointToValue(ActualXAxis, hitPoint); endPoint.Y = ActualArea.PointToValue(ActualYAxis, hitPoint); Rect rect = new Rect(startPoint, endPoint); dataPoint = null; for (int i = 0; i < YValues.Count; i++) { if (isGrouped) { if (i < xValues.Count) { hitPoint.X = xValues[i]; hitPoint.Y = GroupedSeriesYValues[0][i]; } else { return(dataPoint); } } else { hitPoint.X = IsIndexed ? i : xValues[i]; hitPoint.Y = YValues[i]; } if (rect.Contains(hitPoint)) { dataPoint = new ChartDataPointInfo(); dataPoint.Index = i; dataPoint.XData = xValues[i]; dataPoint.YData = (isGrouped) ? GroupedSeriesYValues[0][i] : YValues[i]; dataPoint.Series = this; if (i > -1 && ActualData.Count > i) { dataPoint.Item = ActualData[i]; } break; } } return(dataPoint); }
/// <summary> /// This method used to get the chart data at a mouse position. /// </summary> /// <param name="mousePos"></param> /// <returns></returns> internal override ChartDataPointInfo GetDataPoint(Point mousePos) { double xVal = 0; double yVal = 0; double stackedYValue = double.NaN; dataPoint = null; dataPoint = new ChartDataPointInfo(); 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); dataPoint.XData = xVal; int index = ((ActualXAxis is CategoryAxis) && (!(ActualXAxis as CategoryAxis).IsIndexed)) ? GroupedXValuesIndexes.IndexOf(xVal) : this.GetXValues().IndexOf(xVal); if (index == -1) { return(null); } 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]; } } return(dataPoint); }
protected internal override void SelectedIndexChanged(int newIndex, int oldIndex) { ChartSelectionChangedEventArgs chartSelectionChangedEventArgs; ChartSegment prevSelectedSegment = null; if (ActualArea != null && ActualArea.SelectionBehaviour != null) { // Resets the adornment selection when the mouse pointer moved away from the adornment or clicked the same adornment. if (ActualArea.SelectionBehaviour.SelectionStyle == SelectionStyle.Single) { if (SelectedSegmentsIndexes.Contains(oldIndex)) { SelectedSegmentsIndexes.Remove(oldIndex); } OnResetSegment(oldIndex); } if (prevDataPoint != null && Segments.Count > 0) { prevSelectedSegment = (from segment in Segments where segment is FastLineSegment && (segment as FastLineSegment).xChartVals.Contains(prevDataPoint.XData) select segment).FirstOrDefault() as ChartSegment; } if (newIndex >= 0 && ActualArea.GetEnableSegmentSelection()) { if (!SelectedSegmentsIndexes.Contains(newIndex)) { SelectedSegmentsIndexes.Add(newIndex); } // Selects the adornment when the mouse is over or clicked on adornments(adornment selection). if (adornmentInfo != null && adornmentInfo.HighlightOnSelection) { UpdateAdornmentSelection(newIndex); } if (ActualArea != null && Segments.Count > 0) { var selectedSegment = (from segment in Segments where segment is FastLineSegment && (segment as FastLineSegment).xChartVals.Contains(dataPoint.XData) select segment).FirstOrDefault(); if (selectedSegment != null) { chartSelectionChangedEventArgs = new ChartSelectionChangedEventArgs() { SelectedSegment = selectedSegment, SelectedSegments = Area.SelectedSegments, SelectedSeries = this, SelectedIndex = newIndex, PreviousSelectedIndex = oldIndex, NewPointInfo = GetDataPoint(newIndex), IsSelected = true }; chartSelectionChangedEventArgs.PreviousSelectedSeries = this.ActualArea.PreviousSelectedSeries; if (oldIndex != -1) { chartSelectionChangedEventArgs.PreviousSelectedSegment = prevSelectedSegment; chartSelectionChangedEventArgs.OldPointInfo = GetDataPoint(oldIndex); } (ActualArea as SfChart).OnSelectionChanged(chartSelectionChangedEventArgs); PreviousSelectedIndex = newIndex; prevDataPoint = dataPoint; } } else if (Segments.Count == 0) { triggerSelectionChangedEventOnLoad = true; } } else if (newIndex == -1) { chartSelectionChangedEventArgs = new ChartSelectionChangedEventArgs() { SelectedSegment = null, SelectedSegments = Area.SelectedSegments, SelectedSeries = null, SelectedIndex = newIndex, PreviousSelectedIndex = oldIndex, NewPointInfo = null, OldPointInfo = GetDataPoint(oldIndex), PreviousSelectedSeries = this, IsSelected = false }; if (oldIndex != -1) { chartSelectionChangedEventArgs.PreviousSelectedSegment = prevSelectedSegment; } (ActualArea as SfChart).OnSelectionChanged(chartSelectionChangedEventArgs); PreviousSelectedIndex = newIndex; } } else if (newIndex >= 0 && Segments.Count == 0) { triggerSelectionChangedEventOnLoad = true; } }
/// <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); }