/// <summary>
        /// Get or create a linear numeric axis in the correct dimension.
        /// </summary>
        /// <param name="orientation">Dimension of the axis to create.</param>
        /// <param name="oldAxis">
        /// Old value of the axis in this dimension.
        /// </param>
        /// <returns>New value of the axis in this dimension.</returns>
        private IRangeAxis GetAxis(AxisOrientation orientation, IRangeAxis oldAxis)
        {
            // Check the existing axes for a potential axis
            IRangeAxis axis =
                (from IRangeAxis a in SeriesHost.Axes.OfType<IRangeAxis>()
                 where a.Orientation == orientation
                 select a)
                .FirstOrDefault();

            if (axis == null)
            {
                // Create a new axis if not found
                axis = new LinearAxis
                {
                    Orientation = orientation,
                };
            }

            if (oldAxis != axis)
            {
                // Unregister any existing axis
                if (oldAxis != null)
                {
                    oldAxis.RegisteredListeners.Remove(this);
                }
                
                // Register the new axis
                if (!axis.RegisteredListeners.Contains(this))
                {
                    axis.RegisteredListeners.Add(this);
                }
            }

            return axis;
        }
Exemplo n.º 2
0
 private void OnDependentRangeAxisPropertyChanged(IRangeAxis newValue)
 {
     this.InternalDependentAxis = (IAxis)newValue;
 }
        /// <summary>
        /// Get a point in screen coordinates.
        /// </summary>
        /// <param name="x">Independent value.</param>
        /// <param name="function">The function.</param>
        /// <param name="independent">The independent axis.</param>
        /// <param name="dependent">The dependent axis.</param>
        /// <returns>The point in screen coordinates.</returns>
        private Point GetPoint(double x, Func<double, double> function, IRangeAxis independent, IRangeAxis dependent)
        {
            // Get the dependent value
            double y = double.NaN;
            try
            {
                y = function(x);
            }
            catch (DivideByZeroException)
            {
            }

            // Map the actual values into coordinate values
            return new Point(
                independent.GetPlotAreaCoordinate(x).Value,
                Math.Min(
                    Math.Max(
                        ActualHeight - dependent.GetPlotAreaCoordinate(y).Value,
                        -1),
                    ActualHeight + 1));
        }
Exemplo n.º 4
0
 /// <summary>
 /// Returns the range of values for the axis to include.
 /// </summary>
 /// <param name="rangeAxis">The axis corresponding to the range.</param>
 /// <returns>The range for the axis to include.</returns>
 Range <IComparable> IRangeAxisInformationProvider.GetDesiredRange(IRangeAxis rangeAxis)
 {
     return(OverrideRequestedAxisRange(rangeAxis, (this as IRangeAxisInformationProvider).GetActualRange(rangeAxis)));
 }
 /// <summary>
 /// DependentRangeAxisProperty property changed handler.
 /// </summary>
 /// <param name="newValue">New value.</param>
 private void OnDependentRangeAxisPropertyChanged(IRangeAxis newValue)
 {
     this.InternalDependentAxis = (IAxis)newValue;
 }
        /// <summary>
        /// Get a point in screen coordinates.
        /// </summary>
        /// <param name="x">Independent value.</param>
        /// <param name="function">The function.</param>
        /// <param name="independent">The independent axis.</param>
        /// <param name="dependent">The dependent axis.</param>
        /// <returns>The point in screen coordinates.</returns>
        private Point GetPoint(double x, Func <double, double> function, IRangeAxis independent, IRangeAxis dependent)
        {
            // Get the dependent value
            double y = double.NaN;

            try
            {
                y = function(x);
            }
            catch (DivideByZeroException)
            {
            }

            // Map the actual values into coordinate values
            return(new Point(
                       independent.GetPlotAreaCoordinate(x).Value,
                       Math.Min(
                           Math.Max(
                               ActualHeight - dependent.GetPlotAreaCoordinate(y).Value,
                               -1),
                           ActualHeight + 1)));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Acquires a range 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 accepts a
        /// Control and returns the value that will be plot on the axis.
        /// </param>
        protected void GetRangeAxis(
            IAxis assignedAxis,
            DataPoint firstDataPoint,
            AxisOrientation orientation,
            Func <IRangeAxis> axisInitializationAction,
            Func <IRangeAxis> axisPropertyAccessor,
            Action <IRangeAxis> axisPropertySetter,
            Func <DataPoint, object> dataPointAxisValueGetter)
        {
            if (assignedAxis != null)
            {
                if (assignedAxis.Orientation == orientation)
                {
                    IRangeAxis assignedRangeAxis = assignedAxis as IRangeAxis;
                    if (assignedRangeAxis != null)
                    {
                        object value = dataPointAxisValueGetter(firstDataPoint);
                        if (assignedRangeAxis.CanPlot(value))
                        {
                            axisPropertySetter(assignedRangeAxis);
                            if (!assignedAxis.IsObjectRegistered(this))
                            {
                                assignedRangeAxis.Invalidated += OnAxisInvalidated;
                                this.SeriesHost.RegisterWithAxis(this, (IAxis)assignedRangeAxis);
                            }
                            return;
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.DataPointSeriesWithAxes_AxisCannotPlotValue, value));
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(Properties.Resources.DataPointSeriesWithAxes_ExpectedAxesOfTypeICategoryAxis);
                    }
                }
                else
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Properties.Resources.DataPointSeriesWithAxes_AxisIsIncorrectOrientation, orientation));
                }
            }

            // If current axis is not suitable...
            if (axisPropertyAccessor() == null || !axisPropertyAccessor().CanPlot(dataPointAxisValueGetter(firstDataPoint)))
            {
                // Attempt to find suitable axis
                IRangeAxis axis =
                    SeriesHost.Axes
                    .Cast <IAxis>()
                    .Where(currentAxis => currentAxis.Orientation == orientation &&
                           currentAxis.CanPlot(dataPointAxisValueGetter(firstDataPoint)) &&
                           currentAxis.CanRegister(this))
                    .OfType <IRangeAxis>()
                    .FirstOrDefault();

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

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

                axisPropertySetter(axis);

                if (!axis.IsObjectRegistered(this))
                {
                    axis.Invalidated += OnAxisInvalidated;
                    SeriesHost.RegisterWithAxis(this, baseAxis);
                }
            }
        }
Exemplo n.º 8
0
 /// <summary>
 ///     DependentRangeAxisProperty property changed handler.
 /// </summary>
 /// <param name="newValue">New value.</param>
 private void OnDependentRangeAxisPropertyChanged(IRangeAxis newValue)
 {
     InternalDependentAxis = newValue;
 }
        /// <summary>
        /// Refreshes data from data source and renders the series.
        /// </summary>
        private void Refresh()
        {
            if (SeriesHost == null || ActualWidth == 0)
            {
                return;
            }

            // Ensure we have a function to plot
            Func <double, double> function = Function;

            if (function == null)
            {
                return;
            }

            // Ensure we have axes
            IRangeAxis independent = GetAxis(AxisOrientation.X, IndependentAxis);

            IndependentAxis = independent;
            IRangeAxis dependent = GetAxis(AxisOrientation.Y, DependentAxis);

            DependentAxis = dependent;
            if (!independent.Range.HasData)
            {
                return;
            }

            // Create a geometry that matches the function to plot
            PathGeometry path   = new PathGeometry();
            PathFigure   figure = new PathFigure();

            // Get the range over which we will
            double start = (double)independent.Range.Minimum;
            double end   = (double)independent.Range.Maximum;

            // Adjust the line at each pixel
            double delta = (end - start) / ActualWidth;

            // We'll only add a new line segment when the slope is changing
            // between points
            Point last = GetPoint(start, function, independent, dependent);

            figure.StartPoint = last;
            double slope = double.NaN;

            for (double x = start + delta; x <= end; x += delta)
            {
                Point  next     = GetPoint(x, function, independent, dependent);
                double newSlope = (next.Y - last.Y) / (next.X - last.X);

                if (slope != newSlope)
                {
                    figure.Segments.Add(new LineSegment {
                        Point = last
                    });
                }

                slope = newSlope;
                last  = next;
            }
            figure.Segments.Add(new LineSegment {
                Point = last
            });

            path.Figures.Add(figure);
            Geometry = path;
        }
Exemplo n.º 10
0
        /// <summary>
        /// Get or create a linear numeric axis in the correct dimension.
        /// </summary>
        /// <param name="orientation">Dimension of the axis to create.</param>
        /// <param name="oldAxis">
        /// Old value of the axis in this dimension.
        /// </param>
        /// <returns>New value of the axis in this dimension.</returns>
        private IRangeAxis GetAxis(AxisOrientation orientation, IRangeAxis oldAxis)
        {
            // Check the existing axes for a potential axis
            IRangeAxis axis =
                (from IRangeAxis a in SeriesHost.Axes.OfType<IRangeAxis>()
                 where a.Orientation == orientation
                 select a)
                .FirstOrDefault();

            if (axis == null)
            {
                // Create a new axis if not found
                axis = new LinearAxis
                {
                    Orientation = orientation,
                };
            }

            if (oldAxis != axis)
            {
                // Unregister any existing axis
                if (oldAxis != null)
                {
                    SeriesHost.UnregisterWithAxis(this, oldAxis);
                    oldAxis.Invalidated -= OnAxisInvalidated;
                }

                // Register the new axis
                SeriesHost.RegisterWithAxis(this, axis);
                axis.Invalidated += OnAxisInvalidated;
            }

            return axis;
        }
Exemplo n.º 11
0
 /// <summary>
 /// If data is found returns the minimum and maximum dependent numeric
 /// values. 
 /// </summary>
 /// <param name="rangeAxis">IRangeAxis that needs the data.</param>
 /// <returns>
 /// The range of values or empty if no data is present.
 /// </returns>
 public Range<IComparable> GetDesiredRange(IRangeAxis rangeAxis)
 {
     // Use an empty range so we only plot over the area used by other
     // axes.
     return new Range<IComparable>();
 }
Exemplo n.º 12
0
        /// <summary>
        /// Ensures that if the desired range is below or above zero and the
        /// data does not cross zero then the minimum of the desired range is
        /// adjusted to zero.
        /// </summary>
        /// <param name="rangeAxis">The axis to request the range for.</param>
        /// <param name="range">The range of the data.</param>
        /// <returns>The desired data range.</returns>
        protected override Range<IComparable> OverrideRequestedAxisRange(IRangeAxis rangeAxis, Range<IComparable> range)
        {
            Range<IComparable> desiredRange = base.OverrideRequestedAxisRange(rangeAxis, range);

            if (range.HasData && desiredRange.HasData)
            {
                Range<double> doubleRange = range.ToDoubleRange();
                Range<double> doubleDesiredRange = desiredRange.ToDoubleRange();
                if (rangeAxis == InternalActualDependentAxis)
                {
                    double minimum = doubleDesiredRange.Minimum;
                    double maximum = doubleDesiredRange.Maximum;

                    if (doubleRange.Minimum >= 0.0 && minimum < 0.0)
                    {
                        minimum = 0.0;
                    }
                    if (doubleRange.Maximum <= 0.0 && maximum >= 0.0)
                    {
                        maximum = 0.0;
                    }

                    return new Range<IComparable>(minimum, maximum);
                }
            }
            return desiredRange;
        }
        public void UpdateBody(IRangeAxis rangeAxis)
        {
            if (Body == null)
                return;

            double highPointY = rangeAxis.GetPlotAreaCoordinate(ValueHelper.ToDouble(High)).Value;
            double lowPointY = rangeAxis.GetPlotAreaCoordinate(ValueHelper.ToDouble(Low)).Value;
            double openPointY = rangeAxis.GetPlotAreaCoordinate(ValueHelper.ToDouble(Open)).Value;
            double closePointY = rangeAxis.GetPlotAreaCoordinate(ValueHelper.ToDouble(Close)).Value;

            Thickness margin;
            if (openPointY > closePointY)
            {
                margin = new Thickness(0, highPointY - openPointY, 0, closePointY - lowPointY);
            }
            else
            {
                margin = new Thickness(0, highPointY - closePointY, 0, openPointY - lowPointY);
            }

            Body.Margin = margin;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Overrides the requested axis range to include the width and height
        /// necessary for the bubbles.
        /// </summary>
        /// <param name="rangeAxis">The range axis.</param>
        /// <param name="range">The data range.</param>
        /// <returns>The requested axis range.</returns>
        protected override Range<IComparable> OverrideRequestedAxisRange(IRangeAxis rangeAxis, Range<IComparable> range)
        {
            if (ActiveDataPoints.Any())
            {
                if (rangeAxis == ActualIndependentRangeAxis)
                {
                    double smallestXCoordinate =
                        ActiveDataPoints
                            .Select(dataPoint =>
                                ActualIndependentRangeAxis.GetPlotAreaCoordinate((IComparable)dataPoint.IndependentValue) - dataPoint.ActualWidth)
                            .Min();

                    double largestXCoordinate =
                        ActiveDataPoints
                            .Select(dataPoint =>
                                ActualIndependentRangeAxis.GetPlotAreaCoordinate((IComparable)dataPoint.IndependentValue) + dataPoint.ActualWidth)
                            .Max();

                    return new Range<IComparable>(
                        ActualIndependentRangeAxis.GetPlotAreaCoordinateValueRange(smallestXCoordinate).Minimum,
                        ActualIndependentRangeAxis.GetPlotAreaCoordinateValueRange(largestXCoordinate).Maximum);
                }
                else if (rangeAxis == ActualDependentRangeAxis)
                {
                    double smallestYCoordinate =
                        ActiveDataPoints
                            .Select(dataPoint =>
                                ActualDependentRangeAxis.GetPlotAreaCoordinate((IComparable)dataPoint.DependentValue) - dataPoint.ActualHeight)
                            .Min();

                    double largestYCoordinate =
                        ActiveDataPoints
                            .Select(dataPoint =>
                                ActualDependentRangeAxis.GetPlotAreaCoordinate((IComparable)dataPoint.DependentValue) + dataPoint.ActualHeight)
                            .Max();

                    return new Range<IComparable>(
                        ActualDependentRangeAxis.GetPlotAreaCoordinateValueRange(smallestYCoordinate).Minimum,
                        ActualDependentRangeAxis.GetPlotAreaCoordinateValueRange(largestYCoordinate).Maximum);
                }
            }
            return new Range<IComparable>();
        }