/// <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 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>
 /// 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>
 /// 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 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 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>
        /// 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>
        /// 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>
        /// 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);
                }
            }
        }
Beispiel #10
0
 /// <summary>
 ///     Updates a data point when its actual dependent value has 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 OnDataPointActualDependentValueChanged(DataPoint dataPoint, IComparable oldValue,
                                                                IComparable newValue)
 {
     UpdateDataPoint(dataPoint);
     base.OnDataPointActualDependentValueChanged(dataPoint, oldValue, newValue);
 }
        /// <summary>
        /// Updates the data point when the pie data point's offset ratio is
        /// changed.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="args">Information about the event.</param>
        private void OnPieDataPointOffsetRatioChanged(object sender, RoutedPropertyChangedEventArgs <double> args)
        {
            DataPoint dataPoint = sender as DataPoint;

            dataPoint.BeginAnimation(PieDataPoint.ActualOffsetRatioProperty, "ActualOffsetRatio", args.NewValue, TransitionDuration, this.TransitionEasingFunction);
        }
 /// <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);
 }
Beispiel #13
0
        /// <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);
                }
            }
        }
Beispiel #14
0
 /// <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);
Beispiel #15
0
 /// <summary>
 /// Update axes when the specified data point's actual independent value changes.
 /// </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 OnDataPointActualIndependentValueChanged(DataPoint dataPoint, object oldValue, object newValue)
 {
     UpdateActualIndependentAxis();
     UpdateDataPoint(dataPoint);
     base.OnDataPointActualIndependentValueChanged(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>
 /// 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 == DataPointState.Hidden)
     {
         DetachEventHandlersFromDataPoint(dataPoint);
         PlotArea.Children.Remove(dataPoint);
     }
 }
        /// <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 each point.
        /// </summary>
        /// <param name="dataPoint">The data point to update.</param>
        protected override void UpdateDataPoint(DataPoint dataPoint)
        {
            if (SeriesHost == null || PlotArea == null)
            {
                return;
            }

            object            category        = dataPoint.ActualIndependentValue ?? (this.ActiveDataPoints.IndexOf(dataPoint) + 1);
            Range <UnitValue> coordinateRange = GetCategoryRange(category);

            if (!coordinateRange.HasData)
            {
                return;
            }
            else if (coordinateRange.Maximum.Unit != Unit.Pixels || coordinateRange.Minimum.Unit != Unit.Pixels)
            {
                throw new InvalidOperationException(Properties.Resources.DataPointSeriesWithAxes_ThisSeriesDoesNotSupportRadialAxes);
            }

            double minimum = (double)coordinateRange.Minimum.Value;
            double maximum = (double)coordinateRange.Maximum.Value;

            double plotAreaHeight = ActualDependentRangeAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Range.Maximum).Value;
            IEnumerable <ColumnSeries> columnSeries = SeriesHost.Series.OfType <ColumnSeries>().Where(series => series.ActualIndependentAxis == ActualIndependentAxis);
            int    numberOfSeries       = columnSeries.Count();
            double coordinateRangeWidth = (maximum - minimum);
            double segmentWidth         = coordinateRangeWidth * 0.8;
            double columnWidth          = segmentWidth / numberOfSeries;
            int    seriesIndex          = columnSeries.IndexOf(this);

            double dataPointY = ActualDependentRangeAxis.GetPlotAreaCoordinate(ValueHelper.ToDouble(dataPoint.ActualDependentValue)).Value;
            double zeroPointY = ActualDependentRangeAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Origin).Value;

            double offset     = seriesIndex * Math.Round(columnWidth) + coordinateRangeWidth * 0.1;
            double dataPointX = minimum + offset;

            if (GetIsDataPointGrouped(category))
            {
                // Multiple DataPoints share this category; offset and overlap them appropriately
                IGrouping <object, DataPoint> categoryGrouping = GetDataPointGroup(category);
                int index = categoryGrouping.IndexOf(dataPoint);
                dataPointX  += (index * (columnWidth * 0.2)) / (categoryGrouping.Count() - 1);
                columnWidth *= 0.8;
                Canvas.SetZIndex(dataPoint, -index);
            }

            if (ValueHelper.CanGraph(dataPointY) && ValueHelper.CanGraph(dataPointX) && ValueHelper.CanGraph(zeroPointY))
            {
                dataPoint.Visibility = Visibility.Visible;

                double left  = Math.Round(dataPointX);
                double width = Math.Round(columnWidth);

                double top    = Math.Round(plotAreaHeight - Math.Max(dataPointY, zeroPointY) + 0.5);
                double bottom = Math.Round(plotAreaHeight - Math.Min(dataPointY, zeroPointY) + 0.5);
                double height = bottom - top + 1;

                Canvas.SetLeft(dataPoint, left);
                Canvas.SetTop(dataPoint, top);
                dataPoint.Width  = width;
                dataPoint.Height = height;
            }
            else
            {
                dataPoint.Visibility = Visibility.Collapsed;
            }
        }
 /// <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.SetStyle(ActualDataPointStyle);
     base.PrepareDataPoint(dataPoint, dataContext);
 }
 /// <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>
 /// 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>
 /// Prepares a DataPoint for use.
 /// </summary>
 /// <param name="dataPoint">DataPoint instance.</param>
 protected virtual void PrepareDataPoint(DataPoint 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>
 /// 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(ActualDataPointStyleName) { Source = this });
     base.PrepareDataPoint(dataPoint, dataContext);
 }
 /// <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>
 /// Selects a data point.
 /// </summary>
 /// <param name="dataPoint">The data point to select.</param>
 private void Select(DataPoint dataPoint)
 {
     SelectedItem = dataPoint.DataContext;
 }
        /// <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>
        /// 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>
        /// 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 =
#if SILVERLIGHT
                    _resourceDictionaryEnumerator.Current.ShallowCopy();
#else
                    _resourceDictionaryEnumerator.Current;
#endif
                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(PieDataPoint.ActualDataPointStyleName) { Source = pieDataPoint });
            pieDataPoint.ActualLegendItemStyle = LegendItemStyle ?? (pieDataPoint.Resources[LegendItemStyleName] as Style);
            legendItem.SetBinding(LegendItem.StyleProperty, new Binding(ActualLegendItemStyleName) { Source = pieDataPoint });

            _dataPointLegendItems[dataPoint] = legendItem;
            LegendItems.Add(legendItem);
            UpdateLegendItemIndexes();
        }
 /// <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>
        /// 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>
 /// 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>
 /// 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>
        /// 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(PieDataPoint.ActualDataPointStyleName) { Source = dataPoint });
     legendItem.DataContext = legendDataPoint;
     return legendItem;
 }
 /// <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);
        protected override void UpdateDataItemPlacement(IEnumerable <DefinitionSeries.DataItem> dataItems)
        {
            IAxis actualIndependentAxis = ActualIndependentAxis;

            if ((null != ActualDependentAxis) && (null != actualIndependentAxis))
            {
                double        plotAreaMaximumDependentCoordinate = ActualDependentAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Range.Maximum).Value;
                double        zeroCoordinate = ActualDependentAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Origin ?? 0.0).Value;
                ICategoryAxis actualIndependentCategoryAxis = actualIndependentAxis as ICategoryAxis;
                double        nonCategoryAxisRangeMargin    = (null != actualIndependentCategoryAxis) ? 0 : GetMarginForNonCategoryAxis(actualIndependentAxis);
                foreach (IndependentValueGroup group in IndependentValueGroups)
                {
                    Range <UnitValue> categoryRange = new Range <UnitValue>();
                    if (null != actualIndependentCategoryAxis)
                    {
                        categoryRange = actualIndependentCategoryAxis.GetPlotAreaCoordinateRange(group.IndependentValue);
                    }
                    else
                    {
                        UnitValue independentValueCoordinate = actualIndependentAxis.GetPlotAreaCoordinate(group.IndependentValue);
                        if (ValueHelper.CanGraph(independentValueCoordinate.Value))
                        {
                            categoryRange = new Range <UnitValue>(new UnitValue(independentValueCoordinate.Value - nonCategoryAxisRangeMargin, independentValueCoordinate.Unit), new UnitValue(independentValueCoordinate.Value + nonCategoryAxisRangeMargin, independentValueCoordinate.Unit));
                        }
                    }
                    if (categoryRange.HasData)
                    {
                        double categoryMinimumCoordinate = categoryRange.Minimum.Value;
                        double categoryMaximumCoordinate = categoryRange.Maximum.Value;
                        double padding = 0.1 * (categoryMaximumCoordinate - categoryMinimumCoordinate);
                        categoryMinimumCoordinate += padding;
                        categoryMaximumCoordinate -= padding;

                        double sum = IsStacked100 ?
                                     group.DataItems.Sum(di => Math.Abs(ValueHelper.ToDouble(di.DataPoint.ActualDependentValue))) :
                                     1;
                        if (0 == sum)
                        {
                            sum = 1;
                        }
                        double ceiling = 0;
                        double floor   = 0;
                        foreach (DataItem dataItem in group.DataItems)
                        {
                            DataPoint dataPoint = dataItem.DataPoint;
                            double    value     = IsStacked100 ? (ValueHelper.ToDouble(dataPoint.ActualDependentValue) * (100 / sum)) : ValueHelper.ToDouble(dataPoint.ActualDependentValue);
                            if (ValueHelper.CanGraph(value))
                            {
                                double valueCoordinate  = ActualDependentAxis.GetPlotAreaCoordinate(value).Value;
                                double fillerCoordinate = (0 <= value) ? ceiling : floor;

                                double topCoordinate = 0, leftCoordinate = 0, height = 0, width = 0, deltaCoordinate = 0;
                                if (AxisOrientation.Y == ActualDependentAxis.Orientation)
                                {
                                    topCoordinate = plotAreaMaximumDependentCoordinate - Math.Max(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate);
                                    double bottomCoordinate = plotAreaMaximumDependentCoordinate - Math.Min(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate);
                                    deltaCoordinate = bottomCoordinate - topCoordinate;
                                    height          = (0 < deltaCoordinate) ? deltaCoordinate + 1 : 0;
                                    leftCoordinate  = categoryMinimumCoordinate;
                                    width           = categoryMaximumCoordinate - categoryMinimumCoordinate + 1;
                                }
                                else
                                {
                                    leftCoordinate = Math.Min(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate);
                                    double rightCoordinate = Math.Max(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate);
                                    deltaCoordinate = rightCoordinate - leftCoordinate;
                                    width           = (0 < deltaCoordinate) ? deltaCoordinate + 1 : 0;
                                    topCoordinate   = categoryMinimumCoordinate;
                                    height          = categoryMaximumCoordinate - categoryMinimumCoordinate + 1;
                                }

                                double roundedTopCoordinate = Math.Round(topCoordinate);
                                Canvas.SetTop(dataItem.Container, roundedTopCoordinate);
                                dataPoint.Height = Math.Round(topCoordinate + height - roundedTopCoordinate);
                                double roundedLeftCoordinate = Math.Round(leftCoordinate);
                                Canvas.SetLeft(dataItem.Container, roundedLeftCoordinate);
                                dataPoint.Width      = Math.Round(leftCoordinate + width - roundedLeftCoordinate);
                                dataPoint.Visibility = Visibility.Visible;

                                if (0 <= value)
                                {
                                    ceiling += deltaCoordinate;
                                }
                                else
                                {
                                    floor -= deltaCoordinate;
                                }
                            }
                            else
                            {
                                dataPoint.Visibility = Visibility.Collapsed;
                            }
                        }
                    }
                    else
                    {
                        foreach (DataPoint dataPoint in group.DataItems.Select(di => di.DataPoint))
                        {
                            dataPoint.Visibility = Visibility.Collapsed;
                        }
                    }
                }
            }
        }