/// <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> /// Updates the data point when the independent value is changed. /// </summary> /// <param name="dataPoint">The data point.</param> /// <param name="oldValue">The old value.</param> /// <param name="newValue">The new value.</param> protected override void OnDataPointIndependentValueChanged(DataPoint dataPoint, object oldValue, object newValue) { _dataPointLegendItems[dataPoint].Content = newValue; base.OnDataPointIndependentValueChanged(dataPoint, oldValue, newValue); }
/// <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 a data point. /// </summary> /// <param name="dataPoint">The data point to update.</param> protected override void UpdateDataPoint(DataPoint dataPoint) { PieDataPoint pieDataPoint = (PieDataPoint) dataPoint; pieDataPoint.Width = ActualWidth; pieDataPoint.Height = ActualHeight; UpdatePieDataPointGeometry(pieDataPoint, ActualWidth, ActualHeight); Canvas.SetLeft(pieDataPoint, 0); Canvas.SetTop(pieDataPoint, 0); }
/// <summary> /// Detaches event handlers from a data point. /// </summary> /// <param name="dataPoint">The data point.</param> protected override void DetachEventHandlersFromDataPoint(DataPoint dataPoint) { PieDataPoint pieDataPoint = dataPoint as PieDataPoint; pieDataPoint.ActualRatioChanged -= OnPieDataPointActualRatioChanged; pieDataPoint.ActualOffsetRatioChanged -= OnPieDataPointActualOffsetRatioChanged; pieDataPoint.RatioChanged -= OnPieDataPointRatioChanged; pieDataPoint.OffsetRatioChanged -= OnPieDataPointOffsetRatioChanged; base.DetachEventHandlersFromDataPoint(dataPoint); }
/// <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(Properties.Resources.DataPointSeriesWithAxes_NoSuitableAxisAvailableForPlottingDependentValue); } axis.ShowGridLines = true; axis.Orientation = AxisOrientation.Y; return axis; }); }
/// <summary> /// Creates a legend item for each data point. /// </summary> /// <param name="dataPoint">The data point added.</param> protected override void AddDataPoint(DataPoint dataPoint) { base.AddDataPoint(dataPoint); PieDataPoint pieDataPoint = (PieDataPoint)dataPoint; int index = ActiveDataPoints.IndexOf(dataPoint) + 1; LegendItem legendItem = CreatePieLegendItem(dataPoint, index); // Grab a style enumerator if we don't have one already. if (_resourceDictionaryEnumerator == null) { _resourceDictionaryEnumerator = GetResourceDictionaryWithTargetType(this, typeof(PieDataPoint), true); } if (_resourceDictionaryEnumerator.MoveNext()) { ResourceDictionary paletteResources = _resourceDictionaryEnumerator.Current.ShallowCopy(); pieDataPoint.PaletteResources = paletteResources; pieDataPoint.Resources.MergedDictionaries.Add(paletteResources); } else { pieDataPoint.PaletteResources = null; } pieDataPoint.ActualDataPointStyle = DataPointStyle ?? pieDataPoint.Resources[DataPointStyleName] as Style; pieDataPoint.SetBinding(PieDataPoint.StyleProperty, new Binding { Path = new PropertyPath(PieDataPoint.ActualDataPointStyleName), Source = pieDataPoint }); if (LegendItemStyle != null || pieDataPoint.Resources.ContainsKey(LegendItemStyleName)) pieDataPoint.ActualLegendItemStyle = LegendItemStyle ?? (pieDataPoint.Resources[LegendItemStyleName] as Style); legendItem.SetBinding(LegendItem.StyleProperty, new Binding { Path = new PropertyPath(ActualLegendItemStyleName), Source = pieDataPoint }); _dataPointLegendItems[dataPoint] = legendItem; LegendItems.Add(legendItem); UpdateLegendItemIndexes(); }
/// <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 = (int)DataPointState.PendingRemoval; }
/// <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; SeletecedDataPoint = 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> /// 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 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> /// Selects a data point. /// </summary> /// <param name="dataPoint">The data point to select.</param> private void Select(DataPoint dataPoint) { SelectedItem = dataPoint.DataContext; }
/// <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> /// 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> /// Selects a data point. /// </summary> /// <param name="dataPoint">The data point to select.</param> private void Select(DataPoint dataPoint) { SelectedItem = dataPoint.DataContext; SeletecedDataPoint = dataPoint as PieDataPoint; if (DataPointSelected != null) { DataPointSelected(this, new RotedEventArgs<DataPoint>(dataPoint)); } }
/// <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> /// 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; dataPoint.StateChanged -= OnDataPointStateChanged; }
/// <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> /// 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> /// Removes data point's legend item when the data point is removed. /// </summary> /// <param name="dataPoint">The data point to remove.</param> protected override void RemoveDataPoint(DataPoint dataPoint) { base.RemoveDataPoint(dataPoint); if (dataPoint != null) { LegendItem legendItem = _dataPointLegendItems[dataPoint]; _dataPointLegendItems.Remove(dataPoint); LegendItems.Remove(legendItem); UpdateLegendItemIndexes(); } }
/// <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> /// Creates a legend item from a data point. /// </summary> /// <param name="dataPoint">The data point to use to create the legend item.</param> /// <param name="index">The 1-based index of the Control.</param> /// <returns>The series host legend item.</returns> protected virtual LegendItem CreatePieLegendItem(DataPoint dataPoint, int index) { LegendItem legendItem = CreateLegendItem(this); // Set the Content of the LegendItem legendItem.Content = dataPoint.IndependentValue ?? index; // Create a representative DataPoint for access to styled properties DataPoint legendDataPoint = CreateDataPoint(); legendDataPoint.DataContext = dataPoint.DataContext; if (null != PlotArea) { // Bounce into the visual tree to get default Style applied PlotArea.Children.Add(legendDataPoint); PlotArea.Children.Remove(legendDataPoint); } legendDataPoint.SetBinding(DataPoint.StyleProperty, new Binding { Path = new PropertyPath(PieDataPoint.ActualDataPointStyleName), Source = dataPoint }); legendItem.DataContext = legendDataPoint; return legendItem; }
/// <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) { if (dataPoint.State == (int)DataPointState.Hidden) { DetachEventHandlersFromDataPoint(dataPoint); PlotArea.Children.Remove(dataPoint); } }
/// <summary> /// Updates the data point when the dependent value is changed. /// </summary> /// <param name="dataPoint">The data point.</param> /// <param name="oldValue">The old value.</param> /// <param name="newValue">The new value.</param> protected override void OnDataPointDependentValueChanged(DataPoint dataPoint, IComparable oldValue, IComparable newValue) { UpdateRatios(); base.OnDataPointDependentValueChanged(dataPoint, oldValue, newValue); }
/// <summary> /// Handles data point dependent value 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 OnDataPointDependentValueChanged(DataPoint dataPoint, IComparable oldValue, IComparable newValue) { }
/// <summary> /// Prepares a DataPoint for use. /// </summary> /// <param name="dataPoint">DataPoint instance.</param> protected virtual void PrepareDataPoint(DataPoint dataPoint) { }
/// <summary> /// Handles data point independent value 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 OnDataPointIndependentValueChanged(DataPoint dataPoint, object oldValue, object newValue) { }
/// <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); }
/// <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(Properties.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(Properties.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); } } }