示例#1
0
        private void UpdatePlotOrigin(AxisUpdateContext context)
        {
            if (DefaultOrigin >= this.actualRange.maximum)
            {
                this.normalizedOrigin = 1;
            }
            else if (DefaultOrigin > this.actualRange.minimum)
            {
                this.normalizedOrigin = (DefaultOrigin - this.actualRange.minimum) / (this.actualRange.maximum - this.actualRange.minimum);
            }
            else
            {
                this.normalizedOrigin = 0;
            }

            // apply the plot origin to the series
            if (context.Series != null)
            {
                double plotOrigin = this.IsInverse ? 1 - this.normalizedOrigin : this.normalizedOrigin;
                foreach (ChartSeriesModel model in context.Series)
                {
                    model.SetValue(AxisModel.PlotOriginPropertyKey, plotOrigin);
                }
            }
        }
示例#2
0
        internal override void PlotCore(AxisUpdateContext context)
        {
            int count = this.categories.Count;

            if (count == 0)
            {
                return;
            }

            double step = this.CalculateRelativeStep(count);

            double value  = 0;
            double gap    = this.GapLength * step;
            double length = step - gap;

            double offset = this.actualPlotMode == AxisPlotMode.OnTicks ? 0 : step / 2;
            double position;

            for (int i = 0; i < count; i++)
            {
                AxisCategory category = this.categories[i];
                position = this.IsInverse ? 1 - value - offset : value + offset;
                foreach (DataPoint point in category.Points)
                {
                    CategoricalAxisPlotInfo info = CategoricalAxisPlotInfo.Create(this, value);
                    info.CategoryKey = category.KeySource;
                    info.Position    = position;
                    info.Length      = length;

                    point.SetValueFromAxis(this, info);
                }

                value += step;
            }
        }
示例#3
0
        internal override void UpdateActualRange(AxisUpdateContext context)
        {
            base.UpdateActualRange(context);

            // actual range always starts from zero
            this.actualRange.minimum = 0;
        }
示例#4
0
        internal override void UpdateCore(AxisUpdateContext context)
        {
            this.UpdateActualPlotMode(context.Series);

            this.categories.Clear();
            this.BuildCategories(context);
        }
示例#5
0
        internal override void UpdateCore(AxisUpdateContext context)
        {
            base.UpdateCore(context);

            this.UpdateActualRange(context);
            this.UpdatePlotOrigin(context);

            this.isStacked100 = context.IsStacked100;
        }
示例#6
0
 internal void Plot(AxisUpdateContext context)
 {
     if (!this.isPlotValid)
     {
         // actual points plot
         this.PlotCore(context);
         this.isPlotValid = true;
     }
 }
示例#7
0
        internal void Update(AxisUpdateContext context)
        {
            if (this.isUpdated)
            {
                return;
            }

            this.UpdateCore(context);
            this.isUpdated = true;
        }
示例#8
0
        internal override void PlotCore(AxisUpdateContext context)
        {
            if (!this.CanPlot)
            {
                return;
            }

            decimal delta = this.plotInfo.Max - this.plotInfo.Min;

            if (delta == 0)
            {
                Debug.Assert(false, "Invalid plot pass.");
                return;
            }

            decimal pointPosition, timeSlotPosition, timeSlotLength;
            decimal pointSlotLength;
            decimal extend = this.plotInfo.Extend / 2;

            bool uniform = this.PlotStretch == DateTimePlotStretchMode.Uniform;

            foreach (DateTimePoint value in this.values)
            {
                if (value.Slot == null)
                {
                    // We want to run the tests in both Debug and Release modes.
                    this.ThrowNoTimeSlotException();
                    continue;
                }

                decimal pointTicks = value.Date.Ticks;

                pointPosition    = (pointTicks - this.plotInfo.Min + extend) / delta;
                timeSlotLength   = value.Slot.Ticks / delta;
                timeSlotPosition = pointPosition - (timeSlotLength / 2);

                if (uniform)
                {
                    int pointCount = (value.Point.parent as ChartSeriesModel).DataPointsInternal.Count;
                    pointSlotLength = (1m - this.gapLength) / pointCount;
                }
                else
                {
                    pointSlotLength = (1m - this.gapLength) * timeSlotLength;
                }

                CategoricalAxisPlotInfo currentPlotInfo = CategoricalAxisPlotInfo.Create(this, (double)timeSlotPosition);
                currentPlotInfo.CategoryKey = value.Date;
                currentPlotInfo.Position    = this.IsInverse ? 1 - (double)pointPosition : (double)pointPosition;
                currentPlotInfo.Length      = (double)pointSlotLength;

                value.Point.SetValueFromAxis(this, currentPlotInfo);
            }
        }
示例#9
0
 private void PlotStacked100(AxisUpdateContext context)
 {
     // Note: Stacked100 series cannot be combined with stacked & normal series
     // so we should not plot any non-combined series here.
     foreach (CombinedSeries series in context.CombinedSeries)
     {
         foreach (CombineGroup group in series.Groups)
         {
             this.PlotCombineGroup(group, (stack, value) => value / (stack.PositiveSum - stack.NegativeSum));
         }
     }
 }
示例#10
0
        private void PlotStacked(AxisUpdateContext context)
        {
            foreach (CombinedSeries series in context.CombinedSeries)
            {
                foreach (CombineGroup group in series.Groups)
                {
                    this.PlotCombineGroup(group, (stack, value) => value);
                }
            }

            this.PlotNormal(context.NonCombinedSeries);
        }
        internal override void UpdateCore(AxisUpdateContext context)
        {
            // reset the validation flag
            this.validCategories = true;

            base.UpdateCore(context);

            if (this.validCategories)
            {
                // sort the categories so that they are arranged in a chronological order
                this.categories.Sort(new DateTimeComparer());
            }
        }
示例#12
0
        private void BuildCategories(AxisUpdateContext context)
        {
            if (context.Series == null)
            {
                return;
            }

            bool autoGroup = this.AutoGroup;

            Dictionary <object, AxisCategory> categoriesByKey = new Dictionary <object, AxisCategory>(8);
            AxisPlotDirection direction = this.type == AxisType.First ? AxisPlotDirection.Vertical : AxisPlotDirection.Horizontal;

            foreach (ChartSeriesModel series in context.Series)
            {
                // tell each series what is the plot direction
                series.SetValue(AxisModel.PlotDirectionPropertyKey, direction);

                if (!series.presenter.IsVisible)
                {
                    continue;
                }

                foreach (DataPoint point in series.DataPointsInternal)
                {
                    object value       = this.GetCategoryValue(point);
                    object categoryKey = this.GetCategoryKey(point, value);
                    if (categoryKey == null)
                    {
                        continue;
                    }

                    AxisCategory category;
                    if (autoGroup)
                    {
                        if (!categoriesByKey.TryGetValue(categoryKey, out category))
                        {
                            category = this.CreateCategory(categoryKey, value);
                            categoriesByKey[categoryKey] = category;
                        }
                    }
                    else
                    {
                        category = this.CreateCategory(categoryKey, value);
                    }

                    category.Points.Add(point);
                }
            }
        }
示例#13
0
 internal override void PlotCore(AxisUpdateContext context)
 {
     if (context.IsStacked)
     {
         this.PlotStacked(context);
     }
     else if (context.IsStacked100)
     {
         this.PlotStacked100(context);
     }
     else if (context.Series != null)
     {
         this.PlotNormal(context.Series);
     }
 }
示例#14
0
        internal override void UpdateActualRange(AxisUpdateContext context)
        {
            this.actualRange = new ValueRange <double>(0, 360);

            object userStep = this.GetValue(MajorStepPropertyKey);

            if (userStep != null)
            {
                this.majorStep = (double)userStep;
            }
            else
            {
                this.majorStep = 30;
            }
        }
示例#15
0
        private void UpdateAxis(AxisModel axis, IList <ChartSeriesModel> series)
        {
            Debug.Assert(axis != null, "A series has not found any axes!");
            AxisUpdateContext context = new AxisUpdateContext(axis, series, this.SeriesCombineStrategies.EnumerateValues());

            axis.Update(context);

            bool plotInvalid = axis.isPlotValid;

            // plot points
            axis.Plot(context);

            if (axis.SupportsCombinedPlot && !plotInvalid && this.SeriesCombineStrategies.ContainsKey(axis))
            {
                this.SeriesCombineStrategies[axis].Plot();
            }
        }
示例#16
0
        internal virtual void UpdateActualRange(AxisUpdateContext context)
        {
            // TODO: Do not calculate auto-range if both min and max are user-defined
            this.pointMinMax = this.CalculateRange(context);
            this.actualRange = this.pointMinMax;

            object userMin = this.GetValue(MinimumPropertyKey);

            if (userMin != null)
            {
                this.actualRange.minimum = this.TransformValue((double)userMin);
            }
            object userMax = this.GetValue(MaximumPropertyKey);

            if (userMax != null)
            {
                this.actualRange.maximum = this.TransformValue((double)userMax);
            }

            this.actualRange.maximum = Math.Max(this.actualRange.minimum, this.actualRange.maximum);

            RangeCalculator calculator = new RangeCalculator(this, userMin != null, userMax != null);

            if (!context.IsStacked100)
            {
                this.actualRange = calculator.Extend();
            }

            object userStep = this.GetValue(MajorStepPropertyKey);

            if (userStep != null)
            {
                // LogarithmicAxis.ExponentStep now specifies the actual exponent so we should not "transform" the step value here.
                this.majorStep = (double)userStep;
            }
            else
            {
                this.majorStep = this.CalculateAutoStep(this.actualRange);
            }

            this.actualRange = calculator.RoundToMajorStep(this.majorStep);
            if (this.userTickCount > 0 && userStep == null)
            {
                this.RoundToUserTicks();
            }
        }
示例#17
0
        private ValueRange <double> CalculateRange(AxisUpdateContext context)
        {
            ValueRange <double> range;

            if (context.IsStacked)
            {
                range = this.CalculateStackedRange(context);
            }
            else if (context.IsStacked100)
            {
                range = CalculateStacked100Range(context);
            }
            else
            {
                range = this.CalculateNormalRange(context.Series);
            }

            return(range);
        }
示例#18
0
        private void BuildValues(AxisUpdateContext context)
        {
            this.values.Clear();

            if (context.Series == null)
            {
                return;
            }

            AxisPlotDirection direction = this.type == AxisType.First ? AxisPlotDirection.Vertical : AxisPlotDirection.Horizontal;

            foreach (ChartSeriesModel series in context.Series)
            {
                // tell each series what is the plot direction
                series.SetValue(AxisModel.PlotDirectionPropertyKey, direction);

                if (!series.presenter.IsVisible)
                {
                    continue;
                }

                foreach (DataPoint point in series.DataPointsInternal)
                {
                    object   value = point.GetValueForAxis(this);
                    DateTime date;
                    if (!DateTimeHelper.TryGetDateTime(value, out date))
                    {
                        continue;
                    }

                    DateTimePoint datePoint = new DateTimePoint()
                    {
                        Point = point, Date = date
                    };
                    this.values.Add(datePoint);
                }
            }

            // sort all the values chronologically
            this.values.Sort();
        }
示例#19
0
        private ValueRange <double> CalculateStackedRange(AxisUpdateContext context)
        {
            ValueRange <double> stackedRange = new ValueRange <double>();

            stackedRange.minimum = context.MinimumStackSum;
            stackedRange.maximum = context.MaximumStackSum;

            // loop through non-combined series to check min/max value in their points
            ValueRange <double> nonCombinedRange = this.CalculateNormalRange(context.NonCombinedSeries);

            if (stackedRange.minimum > nonCombinedRange.minimum)
            {
                stackedRange.minimum = nonCombinedRange.minimum;
            }
            if (stackedRange.maximum < nonCombinedRange.maximum)
            {
                stackedRange.maximum = nonCombinedRange.maximum;
            }

            return(stackedRange);
        }
示例#20
0
        internal override void UpdateCore(AxisUpdateContext context)
        {
            this.BuildValues(context);
            if (this.values.Count == 0)
            {
                return;
            }

            this.UpdateActualPlotMode(context.Series);
            this.UpdateActualRange();
            this.FindMinDelta();

            if (!this.CanPlot)
            {
                return;
            }

            this.UpdateUnits();
            this.UpdatePlotInfo();

            this.BuildTimeSlots();
        }
示例#21
0
 internal virtual void UpdateCore(AxisUpdateContext context)
 {
 }
示例#22
0
        private static ValueRange <double> CalculateStacked100Range(AxisUpdateContext context)
        {
            // Note: Stacked100 series cannot be combined with stacked & normal series
            // so we should not loop through any potentially non-combined series here.
            ValueRange <double> stacked100Range = new ValueRange <double>(double.PositiveInfinity, double.NegativeInfinity);

            foreach (CombinedSeries series in context.CombinedSeries)
            {
                foreach (CombineGroup group in series.Groups)
                {
                    foreach (CombineStack stack in group.Stacks)
                    {
                        if (stack.PositiveSum == 0 && stack.NegativeSum == 0)
                        {
                            continue;
                        }

                        if (stack.PositiveSum == 0)
                        {
                            if (stacked100Range.maximum < 0)
                            {
                                stacked100Range.maximum = 0;
                            }

                            if (stacked100Range.minimum > -1)
                            {
                                stacked100Range.minimum = -1;
                            }
                        }
                        else if (stack.NegativeSum == 0)
                        {
                            if (stacked100Range.maximum < 1)
                            {
                                stacked100Range.maximum = 1;
                            }

                            if (stacked100Range.minimum > 0)
                            {
                                stacked100Range.minimum = 0;
                            }
                        }
                        else
                        {
                            double calculatedValue = stack.PositiveSum / (stack.PositiveSum - stack.NegativeSum);
                            if (calculatedValue > stacked100Range.maximum)
                            {
                                stacked100Range.maximum = calculatedValue;
                            }

                            calculatedValue = stack.NegativeSum / (stack.PositiveSum - stack.NegativeSum);
                            if (calculatedValue < stacked100Range.minimum)
                            {
                                stacked100Range.minimum = calculatedValue;
                            }
                        }

                        if (stacked100Range.minimum == -1 && stacked100Range.maximum == 1)
                        {
                            return(stacked100Range);
                        }
                    }
                }
            }

            // Stacked100 series may have had no data points added
            if (stacked100Range.minimum == double.PositiveInfinity)
            {
                stacked100Range.minimum = 0d;
            }

            if (stacked100Range.maximum == double.NegativeInfinity)
            {
                stacked100Range.maximum = 0d;
            }

            return(stacked100Range);
        }