internal override IEnumerable <AxisTickModel> GenerateTicks(ValueRange <decimal> currentVisibleRange) { // use the decimal type for higher accuracy; see the XML comments on the GetVisibleRange method decimal delta = (decimal)this.actualRange.maximum - (decimal)this.actualRange.minimum; if (delta <= 0) { yield break; } double scale = this.layoutStrategy.GetZoom(); double step = this.majorStep; if (scale != 1d) { step = NumericalAxisModel.NormalizeStep(step / scale); } decimal tickStep = (decimal)step; decimal normalizedTickStep = tickStep / delta; currentVisibleRange.minimum -= currentVisibleRange.minimum % normalizedTickStep; currentVisibleRange.maximum += normalizedTickStep - (currentVisibleRange.maximum % normalizedTickStep); decimal startTick, endTick; if (this.IsInverse) { startTick = Math.Max(0, 1 - currentVisibleRange.maximum); endTick = Math.Min(1, 1 - currentVisibleRange.minimum); } else { startTick = Math.Max(0, currentVisibleRange.minimum); endTick = Math.Min(1, currentVisibleRange.maximum); } decimal currentTick = startTick; decimal value = (decimal)this.actualRange.minimum + currentTick * delta; int virtualIndex = (int)((value - (decimal)this.actualRange.minimum) / tickStep); while (currentTick < endTick || RadMath.AreClose((double)currentTick, (double)endTick)) { AxisTickModel tick = new MajorTickModel(); tick.normalizedValue = this.IsInverse ? 1 - currentTick : currentTick; tick.value = (decimal)this.ReverseTransformValue((double)value); tick.virtualIndex = virtualIndex; currentTick += normalizedTickStep; value += tickStep; virtualIndex++; yield return(tick); } }
internal override double CalculateAutoStep(ValueRange <double> range) { if (this.IsLocalValue(NumericalAxisModel.DesiredTickCountPropertyKey)) { double step = (range.maximum - range.minimum) / (this.DesiredTickCount - 1); return(NumericalAxisModel.NormalizeStep(step)); } return(1d); }
public RangeCalculator(NumericalAxisModel axis, bool userMin, bool userMax) { this.range = axis.actualRange; this.extendDirection = axis.extendDirection; this.userMin = userMin; this.userMax = userMax; this.Minimum = this.range.minimum; this.Maximum = this.range.maximum; }
internal override Tuple <object, object> ConvertPointToData(RadPoint coordinates) { object polarValue = null; object radialValue = null; if (this.view != null) { RadRect plotArea = this.plotArea.layoutSlot; double panOffsetX = this.view.PlotOriginX * plotArea.Width; double panOffsetY = this.view.PlotOriginY * plotArea.Height; // todo: The plotArea.Width/Height are the width/height of the whole (zoomed) polar chart, not the visual part of it. RadRect plotAreaVirtualSize = new RadRect(plotArea.X, plotArea.Y, plotArea.Width, plotArea.Height); var polarCoordinates = RadMath.ToPolarCoordinates(new RadPoint(coordinates.X - panOffsetX, coordinates.Y - panOffsetY), plotAreaVirtualSize.Center, true); var radius = polarCoordinates.Item1; var angle = polarCoordinates.Item2; if (this.primaryFirstAxis != null && this.primaryFirstAxis.isUpdated) { NumericalAxisModel polarAxis = this.primaryFirstAxis as NumericalAxisModel; var polarAxisPlotArea = new RadRect(plotAreaVirtualSize.Center.X, plotAreaVirtualSize.Y, plotAreaVirtualSize.Width / 2, plotAreaVirtualSize.Height / 2); polarValue = polarAxis.ConvertPhysicalUnitsToData(radius + polarAxisPlotArea.X, polarAxisPlotArea); } if (this.primarySecondAxis != null && this.primarySecondAxis.isUpdated) { var actualAngle = this.primarySecondAxis.IsInverse ? (360 - angle) % 360 : angle; if (this.primarySecondAxis is CategoricalAxisModel) { CategoricalAxisModel radarAxis = this.primarySecondAxis as CategoricalRadialAxisModel; radialValue = radarAxis.ConvertPhysicalUnitsToData(actualAngle, plotAreaVirtualSize); } else { radialValue = actualAngle; } } } return(new Tuple <object, object>(polarValue, radialValue)); }