/// <summary>
        /// IndependentCategoryAxisProperty property changed handler.
        /// </summary>
        /// <param name="d">ColumnSeries that changed its IndependentCategoryAxis.</param>
        /// <param name="e">Event arguments.</param>
        private static void OnIndependentCategoryAxisPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ColumnSeries  source   = (ColumnSeries)d;
            ICategoryAxis newValue = (ICategoryAxis)e.NewValue;

            source.OnIndependentCategoryAxisPropertyChanged(newValue);
        }
예제 #2
0
        /// <summary>
        /// Gets a range in which to render a data point.
        /// </summary>
        /// <param name="category">The category to retrieve the range for.
        /// </param>
        /// <returns>The range in which to render a data point.</returns>
        protected Range <UnitValue> GetCategoryRange(object category)
        {
            ICategoryAxis categoryAxis = ActualIndependentAxis as CategoryAxis;

            if (categoryAxis != null)
            {
                return(categoryAxis.GetPlotAreaCoordinateRange(category));
            }
            else
            {
                UnitValue?unitValue = ActualIndependentAxis.GetPlotAreaCoordinate(category);
                if (unitValue.HasValue && _dataPointlength.HasValue)
                {
                    double halfLength = _dataPointlength.Value / 2.0;

                    if (unitValue.HasValue)
                    {
                        return(new Range <UnitValue>(
                                   new UnitValue(unitValue.Value.Value - halfLength, unitValue.Value.Unit),
                                   new UnitValue(unitValue.Value.Value + halfLength, unitValue.Value.Unit)));
                    }
                }

                return(new Range <UnitValue>());
            }
        }
예제 #3
0
        /// <summary>
        /// Returns a list of categories used by the series.
        /// </summary>
        /// <param name="categoryAxis">The axis for which to retrieve the categories.
        /// </param>
        /// <returns>A list of categories used by the series.</returns>
        IEnumerable <object> ICategoryAxisInformationProvider.GetCategories(ICategoryAxis categoryAxis)
        {
            IAxis axis = (IAxis)categoryAxis;

            if (axis == null)
            {
                throw new ArgumentNullException("categoryAxis");
            }

            Func <DataPoint, object> selector = null;

            if (axis == InternalActualIndependentAxis)
            {
                if (IndependentValueBinding == null)
                {
                    return(Enumerable.Range(1, ActiveDataPointCount).Cast <object>());
                }
                selector = (dataPoint) => dataPoint.IndependentValue ?? dataPoint.DependentValue;
            }
            else if (axis == InternalActualDependentAxis)
            {
                selector = (dataPoint) => dataPoint.DependentValue;
            }

            return(ActiveDataPoints.Select(selector).Distinct());
        }
 /// <summary>
 /// Update axes when a data point's effective independent value changes.
 /// </summary>
 private void UpdateActualIndependentAxis()
 {
     if (InternalActualIndependentAxis != null)
     {
         ICategoryAxis categoryAxis = InternalActualIndependentAxis as ICategoryAxis;
         if (categoryAxis != null)
         {
             IDataProvider categoryInformationProvider = (IDataProvider)this;
             categoryAxis.DataChanged(categoryInformationProvider, categoryInformationProvider.GetData(categoryAxis));
         }
         IRangeConsumer rangeAxis = InternalActualIndependentAxis as IRangeConsumer;
         if (rangeAxis != null)
         {
             IRangeProvider rangeInformationProvider = (IRangeProvider)this;
             rangeAxis.RangeChanged(rangeInformationProvider, rangeInformationProvider.GetRange(rangeAxis));
         }
     }
 }
예제 #5
0
 /// <summary>
 /// Update axes when a data point's effective independent value changes.
 /// </summary>
 private void UpdateActualIndependentAxis()
 {
     if (InternalActualIndependentAxis != null)
     {
         ICategoryAxis categoryAxis = InternalActualIndependentAxis as ICategoryAxis;
         if (categoryAxis != null)
         {
             ICategoryAxisInformationProvider categoryInformationProvider = (ICategoryAxisInformationProvider)this;
             categoryAxis.Update(categoryInformationProvider, categoryInformationProvider.GetCategories(categoryAxis));
         }
         IRangeAxis rangeAxis = InternalActualIndependentAxis as IRangeAxis;
         if (rangeAxis != null)
         {
             IRangeAxisInformationProvider rangeInformationProvider = (IRangeAxisInformationProvider)this;
             rangeAxis.Update(rangeInformationProvider, rangeInformationProvider.GetActualRange(rangeAxis));
         }
     }
 }
 /// <summary>
 /// IndependentCategoryAxisProperty property changed handler.
 /// </summary>
 /// <param name="newValue">New value.</param>
 private void OnIndependentCategoryAxisPropertyChanged(ICategoryAxis newValue)
 {
     this.InternalIndependentAxis = (IAxis)newValue;
 }
예제 #7
0
        /// <summary>
        /// Acquires a category axis.
        /// </summary>
        /// <param name="assignedAxis">The axis assigned to the exposed
        /// axis property.</param>
        /// <param name="firstDataPoint">A data point used to determine
        /// where a date or numeric axis is required.</param>
        /// <param name="orientation">The desired orientation of the axis.
        /// </param>
        /// <param name="axisInitializationAction">A function that initializes
        /// a newly created axis.</param>
        /// <param name="axisPropertyAccessor">A function that returns the
        /// current value of the property used to store the axis.</param>
        /// <param name="axisPropertySetter">A function that accepts an axis
        /// value and assigns it to the property intended to store a reference
        /// to it.</param>
        /// <param name="dataPointAxisValueGetter">A function that retrieves
        /// the value to plot on the axis from the data point.</param>
        protected void GetCategoryAxis(
            IAxis assignedAxis,
            DataPoint firstDataPoint,
            AxisOrientation orientation,
            Func <ICategoryAxis> axisInitializationAction,
            Func <ICategoryAxis> axisPropertyAccessor,
            Action <ICategoryAxis> axisPropertySetter,
            Func <DataPoint, object> dataPointAxisValueGetter)
        {
            object firstCategoryValue = dataPointAxisValueGetter(firstDataPoint);

            if (assignedAxis != null)
            {
                if (assignedAxis.Orientation == orientation)
                {
                    ICategoryAxis assignedCategoryAxis = assignedAxis as CategoryAxis;
                    if (assignedCategoryAxis != null)
                    {
                        if (assignedCategoryAxis.CanPlot(firstCategoryValue))
                        {
                            axisPropertySetter(assignedCategoryAxis);
                            if (!assignedAxis.IsObjectRegistered(this))
                            {
                                assignedCategoryAxis.Invalidated += OnAxisInvalidated;
                                this.SeriesHost.RegisterWithAxis(this, (IAxis)assignedCategoryAxis);
                            }
                            return;
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.DataPointSeriesWithAxes_AxisCannotPlotValue, firstCategoryValue));
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(Properties.Resources.DataPointSeriesWithAxes_ExpectedAxesOfTypeICategoryAxis);
                    }
                }
                else
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.DataPointSeriesWithAxes_AxisIsIncorrectOrientation, orientation));
                }
            }

            IAxis actualIndependentAxis = axisPropertyAccessor() as IAxis;

            // Only acquire new independent axis if necessary
            if (actualIndependentAxis == null ||
                actualIndependentAxis.Orientation != orientation)
            {
                ICategoryAxis categoryAxis =
                    SeriesHost
                    .Axes.Where(currentAxis => currentAxis.Orientation == orientation)
                    .OfType <ICategoryAxis>()
                    .Where(
                        currentCategoryAxis =>
                        currentCategoryAxis.CanPlot(firstCategoryValue) &&
                        currentCategoryAxis.CanRegister(this))
                    .FirstOrDefault();

                if (categoryAxis == null)
                {
                    categoryAxis             = axisInitializationAction();
                    categoryAxis.Orientation = orientation;
                }

                // Unregister with current axis if it has one.
                if (axisPropertyAccessor() != null)
                {
                    axisPropertyAccessor().Invalidated -= OnAxisInvalidated;
                    ICategoryAxis oldCategoryAxis = axisPropertyAccessor() as ICategoryAxis;
                    this.SeriesHost.UnregisterWithAxis(this, (IAxis)oldCategoryAxis);
                }

                // Set axis to be its independent axis
                axisPropertySetter(categoryAxis);

                if (!categoryAxis.IsObjectRegistered(this))
                {
                    categoryAxis.Invalidated += OnAxisInvalidated;

                    // Register new axis with series host
                    this.SeriesHost.RegisterWithAxis(this, (IAxis)categoryAxis);
                }
            }
        }
예제 #8
0
 /// <summary>
 /// IndependentCategoryAxisProperty property changed handler.
 /// </summary>
 /// <param name="newValue">New value.</param>
 private void OnIndependentCategoryAxisPropertyChanged(ICategoryAxis newValue)
 {
     this.InternalIndependentAxis = (IAxis)newValue;
 }
        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;
                        }
                    }
                }
            }
        }
예제 #10
0
        /// <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);
            ICategoryAxis     categoryAxis    = ActualIndependentAxis as ScrollableCategoryAxis;
            Range <UnitValue> coordinateRange = categoryAxis.GetPlotAreaCoordinateRange(category);

            if (!coordinateRange.HasData)
            {
                return;
            }
            else if (coordinateRange.Maximum.Unit != Unit.Pixels || coordinateRange.Minimum.Unit != Unit.Pixels)
            {
                throw new InvalidOperationException("This series does not support radial axes.");
            }

            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;
            }
        }