I need to calculate the Ticklabels and the Tickrange for charts manually.
I know the \"standard\" algorithm for nice ticks (see http://books.google.de/books?id=fvA7
Here'a better organized C# code.
public class NiceScale
{
public double NiceMin { get; set; }
public double NiceMax { get; set; }
public double TickSpacing { get; private set; }
private double _minPoint;
private double _maxPoint;
private double _maxTicks = 5;
private double _range;
/**
* Instantiates a new instance of the NiceScale class.
*
* @param min the minimum data point on the axis
* @param max the maximum data point on the axis
*/
public NiceScale(double min, double max)
{
_minPoint = min;
_maxPoint = max;
Calculate();
}
/**
* Calculate and update values for tick spacing and nice
* minimum and maximum data points on the axis.
*/
private void Calculate()
{
_range = NiceNum(_maxPoint - _minPoint, false);
TickSpacing = NiceNum(_range / (_maxTicks - 1), true);
NiceMin = Math.Floor(_minPoint / TickSpacing) * TickSpacing;
NiceMax = Math.Ceiling(_maxPoint / TickSpacing) * TickSpacing;
}
/**
* Returns a "nice" number approximately equal to range Rounds
* the number if round = true Takes the ceiling if round = false.
*
* @param range the data range
* @param round whether to round the result
* @return a "nice" number to be used for the data range
*/
private double NiceNum(double range, bool round)
{
double exponent; /** exponent of range */
double fraction; /** fractional part of range */
double niceFraction; /** nice, rounded fraction */
exponent = Math.Floor(Math.Log10(range));
fraction = range / Math.Pow(10, exponent);
if (round) {
if (fraction < 1.5)
niceFraction = 1;
else if (fraction < 3)
niceFraction = 2;
else if (fraction < 7)
niceFraction = 5;
else
niceFraction = 10;
} else {
if (fraction <= 1)
niceFraction = 1;
else if (fraction <= 2)
niceFraction = 2;
else if (fraction <= 5)
niceFraction = 5;
else
niceFraction = 10;
}
return niceFraction * Math.Pow(10, exponent);
}
/**
* Sets the minimum and maximum data points for the axis.
*
* @param minPoint the minimum data point on the axis
* @param maxPoint the maximum data point on the axis
*/
public void SetMinMaxPoints(double minPoint, double maxPoint)
{
_minPoint = minPoint;
_maxPoint = maxPoint;
Calculate();
}
/**
* Sets maximum number of tick marks we're comfortable with
*
* @param maxTicks the maximum number of tick marks for the axis
*/
public void SetMaxTicks(double maxTicks)
{
_maxTicks = maxTicks;
Calculate();
}
}