Beispiel #1
0
        /// <summary>
        /// Calculates the length of the data points.
        /// </summary>
        protected void CalculateDataPointLength()
        {
            if (!(ActualIndependentAxis is ICategoryAxis))
            {
                IEnumerable <UnitValue> values =
                    ActiveDataPoints
                    .Select(dataPoint => ActualIndependentAxis.GetPlotAreaCoordinate(dataPoint.ActualIndependentValue))
                    .Where(value => ValueHelper.CanGraph(value.Value))
                    .OrderBy(value => value.Value)
                    .ToList();

                _dataPointlength =
                    EnumerableFunctions.Zip(
                        values,
                        values.Skip(1),
                        (left, right) => new Range <double>(left.Value, right.Value))
                    .Select(range => range.Maximum - range.Minimum)
                    .MinOrNullable();
            }
        }
        /// <summary>
        /// Gets the margin to use for an independent axis that does not implement ICategoryAxis.
        /// </summary>
        /// <param name="axis">Axis to get the margin for.</param>
        /// <returns>Margin for axis.</returns>
        private double GetMarginForNonCategoryAxis(IAxis axis)
        {
            Debug.Assert(!(axis is ICategoryAxis), "This method is unnecessary for ICategoryAxis.");

            // Find the smallest distance between two independent value plot area coordinates
            double smallestDistance = double.MaxValue;
            double lastCoordinate   = double.NaN;

            foreach (double coordinate in
                     IndependentValueGroupsOrderedByIndependentValue
                     .Select(g => axis.GetPlotAreaCoordinate(g.IndependentValue).Value)
                     .Where(v => ValueHelper.CanGraph(v)))
            {
                if (!double.IsNaN(lastCoordinate))
                {
                    double distance = coordinate - lastCoordinate;
                    if (distance < smallestDistance)
                    {
                        smallestDistance = distance;
                    }
                }
                lastCoordinate = coordinate;
            }
            // Return the margin
            if (double.MaxValue == smallestDistance)
            {
                // No smallest distance because <= 1 independent values to plot
                FrameworkElement element = axis as FrameworkElement;
                if (null != element)
                {
                    // Use width of provided axis so single column scenario looks good
                    return(element.GetMargin(axis));
                }
                else
                {
                    // No information to work with; no idea what margin to return
                    throw new NotSupportedException();
                }
            }
            else
            {
                // Found the smallest distance; margin is half of that
                return(smallestDistance / 2);
            }
        }
        /// <summary>
        /// Gets the margin to use for an independent axis that does not implement ICategoryAxis.
        /// </summary>
        /// <param name="axis">Axis to get the margin for.</param>
        /// <returns>Margin for axis.</returns>
        private double GetMarginForNonCategoryAxis(IAxis axis)
        {
            Debug.Assert(!(axis is ICategoryAxis), "This method is unnecessary for ICategoryAxis.");

            // Find the smallest distance between two independent value plot area coordinates
            double smallestDistance = double.MaxValue;
            double lastCoordinate = double.NaN;
            foreach (double coordinate in
                IndependentValueGroupsOrderedByIndependentValue
                    .Select(g => axis.GetPlotAreaCoordinate(g.IndependentValue).Value)
                    .Where(v => ValueHelper.CanGraph(v)))
            {
                if (!double.IsNaN(lastCoordinate))
                {
                    double distance = coordinate - lastCoordinate;
                    if (distance < smallestDistance)
                    {
                        smallestDistance = distance;
                    }
                }
                lastCoordinate = coordinate;
            }
            // Return the margin
            if (double.MaxValue == smallestDistance)
            {
                // No smallest distance because <= 1 independent values to plot
                FrameworkElement element = axis as FrameworkElement;
                if (null != element)
                {
                    // Use width of provided axis so single column scenario looks good
                    return element.GetMargin(axis);
                }
                else
                {
                    // No information to work with; no idea what margin to return
                    throw new NotSupportedException();
                }
            }
            else
            {
                // Found the smallest distance; margin is half of that
                return smallestDistance / 2;
            }
        }
        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;
                        }
                    }
                }
            }
        }