#region PDFsharp Charting - A .NET charting library based on PDFsharp // // Authors: // Niklas Schneider // // Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany) // // http://www.pdfsharp.com // http://sourceforge.net/projects/pdfsharp // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. #endregion using System; namespace PdfSharp.Charting.Renderers { /// /// Represents the base class for all Y axis renderer. /// internal abstract class YAxisRenderer : AxisRenderer { /// /// Initializes a new instance of the YAxisRenderer class with the specified renderer parameters. /// internal YAxisRenderer(RendererParameters parms) : base(parms) { } /// /// Calculates optimal minimum/maximum scale and minor/major tick based on yMin and yMax. /// protected void FineTuneYAxis(AxisRendererInfo rendererInfo, double yMin, double yMax) { if (yMin == double.MaxValue && yMax == double.MinValue) { // No series data given. yMin = 0.0f; yMax = 0.9f; } if (yMin == yMax) { if (yMin == 0) yMax = 0.9f; else if (yMin < 0) yMax = 0; else if (yMin > 0) yMax = yMin + 1; } // If the ratio between yMax to yMin is more than 1.2, the smallest number will be set too zero. // It's Excel's behavior. if (yMin != 0) { if (yMin < 0 && yMax < 0) { if (yMin / yMax >= 1.2) yMax = 0; } else if (yMax / yMin >= 1.2) yMin = 0; } double deltaYRaw = yMax - yMin; int digits = (int)(Math.Log(deltaYRaw, 10) + 1); double normed = deltaYRaw / Math.Pow(10, digits) * 10; double normedStepWidth = 1; if (normed < 2) normedStepWidth = 0.2f; else if (normed < 5) normedStepWidth = 0.5f; AxisRendererInfo yari = rendererInfo; double stepWidth = normedStepWidth * Math.Pow(10.0, digits - 1.0); if (yari._axis == null || double.IsNaN(yari._axis._majorTick)) yari.MajorTick = stepWidth; else yari.MajorTick = yari._axis._majorTick; double roundFactor = stepWidth * 0.5; if (yari._axis == null || double.IsNaN(yari._axis.MinimumScale)) { double signumMin = (yMin != 0) ? yMin / Math.Abs(yMin) : 0; yari.MinimumScale = (int)(Math.Abs((yMin - roundFactor) / stepWidth) - (1 * signumMin)) * stepWidth * signumMin; } else yari.MinimumScale = yari._axis.MinimumScale; if (yari._axis == null || double.IsNaN(yari._axis.MaximumScale)) { double signumMax = (yMax != 0) ? yMax / Math.Abs(yMax) : 0; yari.MaximumScale = (int)(Math.Abs((yMax + roundFactor) / stepWidth) + (1 * signumMax)) * stepWidth * signumMax; } else yari.MaximumScale = yari._axis.MaximumScale; if (yari._axis == null || double.IsNaN(yari._axis._minorTick)) yari.MinorTick = yari.MajorTick / 5; else yari.MinorTick = yari._axis._minorTick; } /// /// Returns the default tick labels format string. /// protected override string GetDefaultTickLabelsFormat() { return "0.0"; } } }