genLabels method
Generates nice axis labels for a graph and return them as a list of Strings. From https://github.com/alexreisner/smart_chart/blob/master/lib/smart_chart/vendor/nice_numbers.rb
Takes graph left
, right
(data range from min to max), and an options map:
nticks
- number of ticks (target, won't be hit exactly)
scale
- number of digits to the right of the decimal point in
labels; null to have the algorithm choose the best value (=default)
tightStyle
- (default=true), tight means min and max
labels are min and max data values, loose means min label is less than
min data value and max label is greater than max data value
This is an implementation of Paul Heckbert's "Nice Numbers for Graph Labels" algorithm, as described in the Graphics Gems book: http://books.google.com/books?id=fvA7zLEFWZgC&pg=PA61&lpg=PA61#v=onepage
See also http://www.justintalbot.com/research/axis-labeling/ for an improved algorithm which considers font sizes etc.
Implementation
static List<String> genLabels(double left, double right,
{bool tightStyle = true, int nticks = 5, int scale}) {
double min = left, max = right;
if (left > right) // also works for this case
{
min = right;
max = left;
}
// find min, max, and interval
double range = nicenum(max - min, false);
double d = nicenum(range / (nticks - 1), true); // tick mark spacing
double graphmin = (min / d).floor() * d; // graph range min
double graphmax = (max / d).ceil() * d; // graph range max
// define # of fractional digits to show
int nfrac = scale;
if (nfrac == null) {
double log10d = math.log(d) / math.ln10;
nfrac = math.max(-log10d.floor(), 0);
}
// generate label positions
List<String> marks = [];
for (double x = graphmin; x < graphmax + 0.5 * d; x += d) {
marks.add("${x.toStringAsFixed(nfrac)}");
}
// tighten up ends if necessary
if (tightStyle) {
marks[0] = min.toStringAsFixed(nfrac);
marks[marks.length - 1] = max.toStringAsFixed(nfrac);
}
// if(left > right)
// {
// marks = List.from(marks.reversed);
// }
return marks;
}