# Algorithm for graphically spacing items

I am developing a chart and graph library and am having trouble developing an algorithm.

**This is not a homework assignment for a student. See my open source project: https://github.com/eddieios/CoreChart

The algorithm is to space the Y axis labels in a given coordinate graphical space. It should space the labels at about 50 pixels apart, but have no less than 5 labels. All data points are assumed to be positive integers. The labels should be multiples of 5 (so as to have nice clean numbers). The last label can be smaller or larger than the maximum possible value, but it should be the closer of the two. The algorithm inputs are 1) the maximum possible value from the chart data, 2) the height of the graphical space. The output is a list of labels and their vertical positions.

For example:

• Maximum possible chart value = 79
• Height of graphical space = 200

Output would be:

• Label: 0, Vertical Position: 0
• Label: 20, Vertical Position: 50
• Label: 40, Vertical Position: 100
• Label: 60, Vertical Position: 150
• Label: 80, Vertical Position: 200

I have written the following code (Obj-C). But I'm having trouble handling end-cases. For example, if the maxValue = 39, then the labels are set 5 apart. The optimal case here would be to set labels 10 apart. There's something about I'm deciding how many labels there should be that isn't working for all cases.

int maxValue = 39;
float graphHeight = 259.0f;

int numLevels = (int)(graphHeight / 50.0f);

float offset = (int)(maxValue / (float)numLevels);
offset /= 5;
offset = (float)((int)(offset + 0.5));
offset *= 5;

CGFloat stepY = graphHeight * ((float)offset/maxValue);

for (int i = 0; i <= numLevels; i++) {
NSLog(@"label %f position %f", i*offset, i*stepY);
}

• Look at gnuplot or the plotting library of asymptote. – vonbrand Feb 19 '13 at 12:45
• I think this should be on Stack Overflow. – Raphael Feb 20 '13 at 6:59

One possible approach which does not require any hairy arguments is to come up with a "nicety" measure, find a range of offsets, and choose the best one. Usually rounding errors are accounted for by taking a $\pm 1$ (in your case $\pm 5$) modification from the starting point. In your case, you would calculate the nicety measure for both $5$ and $10$, and if your nicety measure is reasonable, choose $10$ over $5$.