/// <summary> /// Retrieves the value for a given access from a data point. /// </summary> /// <param name="dataPoint">The data point to retrieve the value from.</param> /// <param name="axis">The axis to retrieve the value for.</param> /// <returns>A function that returns a value appropriate for the axis /// when provided a DataPoint.</returns> protected virtual object GetActualDataPointAxisValue(DataPoint dataPoint, IAxis axis) { if (axis == InternalActualIndependentAxis) { return dataPoint.ActualIndependentValue; } else if (axis == InternalActualDependentAxis) { return dataPoint.ActualDependentValue; } return null; }
/// <summary> /// Detaches size change and actual size change event handlers from the /// data point. /// </summary> /// <param name="dataPoint">The data point.</param> protected override void DetachEventHandlersFromDataPoint(DataPoint dataPoint) { BubbleDataPoint bubbleDataPoint = (BubbleDataPoint)dataPoint; bubbleDataPoint.SizePropertyChanged -= BubbleDataPointSizePropertyChanged; bubbleDataPoint.ActualSizePropertyChanged -= BubbleDataPointActualSizePropertyChanged; base.DetachEventHandlersFromDataPoint(dataPoint); }
/// <summary> /// Prepares a bubble data point by binding the size value binding to /// the size property. /// </summary> /// <param name="dataPoint">The data point to prepare.</param> /// <param name="dataContext">The data context of the data point. /// </param> protected override void PrepareDataPoint(DataPoint dataPoint, object dataContext) { base.PrepareDataPoint(dataPoint, dataContext); BubbleDataPoint bubbleDataPoint = (BubbleDataPoint)dataPoint; bubbleDataPoint.SetBinding(BubbleDataPoint.SizeProperty, SizeValueBinding ?? DependentValueBinding ?? IndependentValueBinding); }
/// <summary> /// Removes a data point from the plot area. /// </summary> /// <param name="dataPoint">The data point to remove.</param> protected virtual void RemoveDataPoint(DataPoint dataPoint) { if (dataPoint.IsSelected) { Unselect(dataPoint); } ActiveDataPointCount--; dataPoint.State = DataPointState.PendingRemoval; }
/// <summary> /// Adds a data point to the plot area. /// </summary> /// <param name="dataPoint">The data point to add to the plot area. /// </param> protected virtual void AddDataPoint(DataPoint dataPoint) { if (dataPoint.IsSelected) { Select(dataPoint); } if (PlotArea != null) { // Positioning data point outside the visible area. Canvas.SetLeft(dataPoint, float.MinValue); Canvas.SetTop(dataPoint, float.MinValue); dataPoint.IsSelectionEnabled = IsSelectionEnabled; AttachEventHandlersToDataPoint(dataPoint); PlotArea.Children.Insert(GetInsertionIndex(dataPoint), dataPoint); ActiveDataPointCount++; } }
/// <summary> /// Method called to get series to acquire the axes it needs. Acquires /// no axes by default. /// </summary> /// <param name="firstDataPoint">The first data point.</param> protected abstract void GetAxes(DataPoint firstDataPoint);
/// <summary> /// This method updates a single data point. /// </summary> /// <param name="dataPoint">The data point to update.</param> protected override void UpdateDataPoint(DataPoint dataPoint) { double PlotAreaHeight = ActualDependentRangeAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Range.Maximum).Value; double dataPointX = ActualIndependentAxis.GetPlotAreaCoordinate(dataPoint.ActualIndependentValue).Value; double dataPointY = ActualDependentRangeAxis.GetPlotAreaCoordinate(dataPoint.ActualDependentValue).Value; if (ValueHelper.CanGraph(dataPointX) && ValueHelper.CanGraph(dataPointY)) { dataPoint.Visibility = Visibility.Visible; // Set the Position Canvas.SetLeft( dataPoint, Math.Round(dataPointX - (dataPoint.ActualWidth / 2))); Canvas.SetTop( dataPoint, Math.Round(PlotAreaHeight - (dataPointY + (dataPoint.ActualHeight / 2)))); } else { dataPoint.Visibility = Visibility.Collapsed; } }
/// <summary> /// Returns the DataItem corresponding to the specified DataPoint. /// </summary> /// <param name="dataPoint">Specified DataPoint.</param> /// <returns>Corresponding DataItem.</returns> protected DataItem DataItemFromDataPoint(DataPoint dataPoint) { return DataItems.Where(di => di.DataPoint == dataPoint).Single(); }
/// <summary> /// Updates the visual representation of a single data point in the plot /// area. /// </summary> /// <param name="dataPoint">The data point to update.</param> protected abstract void UpdateDataPoint(DataPoint dataPoint);
/// <summary> /// Detaches event handlers from a data point. /// </summary> /// <param name="dataPoint">The data point.</param> protected virtual void DetachEventHandlersFromDataPoint(DataPoint dataPoint) { dataPoint.IsSelectedChanged -= OnDataPointIsSelectedChanged; dataPoint.ActualDependentValueChanged -= OnDataPointActualDependentValueChanged; dataPoint.ActualIndependentValueChanged -= OnDataPointActualIndependentValueChanged; dataPoint.DependentValueChanged -= OnDataPointDependentValueChanged; dataPoint.IndependentValueChanged -= OnDataPointIndependentValueChanged; }
/// <summary> /// Selects a data point. /// </summary> /// <param name="dataPoint">The data point to select.</param> private void Select(DataPoint dataPoint) { SelectedItem = dataPoint.DataContext; }
/// <summary> /// Unselects a data point. /// </summary> /// <param name="dataPoint">The data point to unselect.</param> private void Unselect(DataPoint dataPoint) { if (dataPoint.DataContext.Equals(SelectedItem)) { SelectedItem = null; } }
/// <summary> /// Attaches event handlers to a data point. /// </summary> /// <param name="dataPoint">The data point.</param> protected virtual void AttachEventHandlersToDataPoint(DataPoint dataPoint) { dataPoint.IsSelectedChanged += OnDataPointIsSelectedChanged; dataPoint.ActualDependentValueChanged += OnDataPointActualDependentValueChanged; dataPoint.ActualIndependentValueChanged += OnDataPointActualIndependentValueChanged; dataPoint.DependentValueChanged += OnDataPointDependentValueChanged; dataPoint.IndependentValueChanged += OnDataPointIndependentValueChanged; dataPoint.StateChanged += OnDataPointStateChanged; }
/// <summary> /// Method called to get the axes that the series needs. /// </summary> /// <param name="firstDataPoint">The first data point.</param> /// <param name="independentAxisPredicate">A predicate that returns /// a value indicating whether an axis is an acceptable candidate for /// the series independent axis.</param> /// <param name="independentAxisFactory">A function that creates an /// acceptable independent axis.</param> /// <param name="dependentAxisPredicate">A predicate that returns /// a value indicating whether an axis is an acceptable candidate for /// the series dependent axis.</param> /// <param name="dependentAxisFactory">A function that creates an /// acceptable dependent axis.</param> protected virtual void GetAxes(DataPoint firstDataPoint, Func<IAxis, bool> independentAxisPredicate, Func<IAxis> independentAxisFactory, Func<IAxis, bool> dependentAxisPredicate, Func<IAxis> dependentAxisFactory) { Func<IAxis, bool> actualIndependentAxisPredicate = (axis) => independentAxisPredicate(axis) && axis.CanPlot(firstDataPoint.IndependentValue); IAxis workingIndependentAxis = null; if (this.InternalActualIndependentAxis == null) { if (this.InternalIndependentAxis != null) { if (actualIndependentAxisPredicate(this.InternalIndependentAxis)) { workingIndependentAxis = this.InternalIndependentAxis; } else { throw new InvalidOperationException(ModernUI.Toolkit.Data.Charting.Resources.DataPointSeriesWithAxes_GetAxes_AssignedIndependentAxisCannotBeUsed); } } if (workingIndependentAxis == null) { workingIndependentAxis = this.SeriesHost.Axes.FirstOrDefault(actualIndependentAxisPredicate); } if (workingIndependentAxis == null) { workingIndependentAxis = independentAxisFactory(); } this.InternalActualIndependentAxis = workingIndependentAxis; if (!workingIndependentAxis.RegisteredListeners.Contains(this)) { workingIndependentAxis.RegisteredListeners.Add(this); } if (!this.SeriesHost.Axes.Contains(workingIndependentAxis)) { this.SeriesHost.Axes.Add(workingIndependentAxis); } } Func<IAxis, bool> actualDependentAxisPredicate = (axis) => dependentAxisPredicate(axis) && axis.CanPlot(firstDataPoint.DependentValue); IAxis workingDependentAxis = null; if (this.InternalActualDependentAxis == null) { if (this.InternalDependentAxis != null) { if (actualDependentAxisPredicate(this.InternalDependentAxis)) { workingDependentAxis = this.InternalDependentAxis; } else { throw new InvalidOperationException(ModernUI.Toolkit.Data.Charting.Resources.DataPointSeriesWithAxes_GetAxes_AssignedDependentAxisCannotBeUsed); } } if (workingDependentAxis == null) { workingDependentAxis = InternalActualIndependentAxis.DependentAxes.Concat(this.SeriesHost.Axes).FirstOrDefault(actualDependentAxisPredicate); } if (workingDependentAxis == null) { workingDependentAxis = dependentAxisFactory(); } this.InternalActualDependentAxis = workingDependentAxis; if (!workingDependentAxis.RegisteredListeners.Contains(this)) { workingDependentAxis.RegisteredListeners.Add(this); } // Only add axis to the axes collection of the series host if // it is not a dependent axis belonging to the acquired // independent axis. if (!this.SeriesHost.Axes.Contains(workingDependentAxis) && !InternalActualIndependentAxis.DependentAxes.Contains(workingDependentAxis)) { this.SeriesHost.Axes.Add(workingDependentAxis); } } }
/// <summary> /// Updates the data point's visual representation. /// </summary> /// <param name="dataPoint">The data point.</param> protected override void UpdateDataPoint(DataPoint dataPoint) { double maximumDiameter = Math.Min(PlotAreaSize.Width, PlotAreaSize.Height) * MaximumBubbleSizeAsRatioOfSmallestDimension; BubbleDataPoint bubbleDataPoint = (BubbleDataPoint)dataPoint; double ratioOfLargestBubble = (_rangeOfActualSizeValues.HasData && _rangeOfActualSizeValues.Maximum != 0.0 && bubbleDataPoint.ActualSize >= 0.0) ? Math.Abs(bubbleDataPoint.ActualSize) / _rangeOfActualSizeValues.Maximum : 0.0; bubbleDataPoint.Width = ratioOfLargestBubble * maximumDiameter; bubbleDataPoint.Height = ratioOfLargestBubble * maximumDiameter; double left = (ActualIndependentAxis.GetPlotAreaCoordinate(bubbleDataPoint.ActualIndependentValue)).Value - (bubbleDataPoint.Width / 2.0); double top = (PlotAreaSize.Height - (bubbleDataPoint.Height / 2.0)) - ActualDependentRangeAxis.GetPlotAreaCoordinate(bubbleDataPoint.ActualDependentValue).Value; if (ValueHelper.CanGraph(left) && ValueHelper.CanGraph(top)) { dataPoint.Visibility = Visibility.Visible; Canvas.SetLeft(bubbleDataPoint, left); Canvas.SetTop(bubbleDataPoint, top); } else { dataPoint.Visibility = Visibility.Collapsed; } }
/// <summary> /// Prepares a data point by extracting binding it to a data context /// object. /// </summary> /// <param name="dataPoint">A data point.</param> /// <param name="dataContext">A data context object.</param> protected virtual void PrepareDataPoint(DataPoint dataPoint, object dataContext) { // Create a Control with DataContext set to the data source dataPoint.DataContext = dataContext; // Set bindings for IndependentValue/DependentValue if (IndependentValueBinding != null) { dataPoint.SetBinding(DataPoint.IndependentValueProperty, IndependentValueBinding); } if (DependentValueBinding == null) { dataPoint.SetBinding(DataPoint.DependentValueProperty, new Binding()); } else { dataPoint.SetBinding(DataPoint.DependentValueProperty, DependentValueBinding); } }
/// <summary> /// Prepares a DataPoint for use. /// </summary> /// <param name="dataPoint">DataPoint instance.</param> protected virtual void PrepareDataPoint(DataPoint dataPoint) { }
/// <summary> /// Handles data point state property change. /// </summary> /// <param name="dataPoint">The data point.</param> /// <param name="oldValue">The old value.</param> /// <param name="newValue">The new value.</param> protected virtual void OnDataPointStateChanged(DataPoint dataPoint, DataPointState oldValue, DataPointState newValue) { }
/// <summary> /// Acquire a horizontal linear axis and a vertical linear axis. /// </summary> /// <param name="firstDataPoint">The first data point.</param> protected override void GetAxes(DataPoint firstDataPoint) { GetAxes( firstDataPoint, (axis) => axis.Orientation == AxisOrientation.X, () => { IAxis axis = CreateRangeAxisFromData(firstDataPoint.IndependentValue); if (axis == null) { axis = new CategoryAxis(); } axis.Orientation = AxisOrientation.X; return axis; }, (axis) => axis.Orientation == AxisOrientation.Y && axis is IRangeAxis, () => { DisplayAxis axis = (DisplayAxis)CreateRangeAxisFromData(firstDataPoint.DependentValue); if (axis == null) { throw new InvalidOperationException(ModernUI.Toolkit.Data.Charting.Resources.DataPointSeriesWithAxes_NoSuitableAxisAvailableForPlottingDependentValue); } axis.ShowGridLines = true; axis.Orientation = AxisOrientation.Y; return axis; }); }
/// <summary> /// Returns the index at which to insert data point in the plot area /// child collection. /// </summary> /// <param name="dataPoint">The data point to retrieve the insertion /// index for.</param> /// <returns>The insertion index.</returns> protected virtual int GetInsertionIndex(DataPoint dataPoint) { return PlotArea.Children.Count; }
/// <summary> /// Prepares a DataPoint for use. /// </summary> /// <param name="dataPoint">DataPoint instance.</param> protected override void PrepareDataPoint(DataPoint dataPoint) { base.PrepareDataPoint(dataPoint); dataPoint.SizeChanged += new SizeChangedEventHandler(DataPointSizeChanged); }
/// <summary> /// Sets the style of the data point to the single style used for all /// data points. /// </summary> /// <param name="dataPoint">The data point to apply the style to. /// </param> /// <param name="dataContext">The object associated with the data point. /// </param> protected override void PrepareDataPoint(DataPoint dataPoint, object dataContext) { dataPoint.SetBinding(DataPoint.StyleProperty, new Binding() { Path = new PropertyPath(ActualDataPointStyleName), Source = this }); base.PrepareDataPoint(dataPoint, dataContext); }