Я рисую график, где на горизонтальной оси есть время, а на вертикальной оси - цена.
Цена может варьироваться от 0,23487 до 0,8746 или от 20,47 до 45,48 или от 1,4578 до 1,6859 или от 9000 до 12000 ... Вы понимаете, что любой диапазон может быть там. Также точность чисел может отличаться (но обычно это 2 десятичных знака или 4 десятичных знака).
Теперь по вертикальной оси мне нужно показать цены, но не все из них, только некоторые значимые уровни. Мне нужно показать как можно больше значимых уровней, но эти уровни не должны быть ближе друг к другу, чем 30 пикселей (.
Так что, если у меня есть график с данными, цены которого колеблются от 1.4567 до 1.6789, а высота графика составляет 500, я могу показать максимум 16 значимых уровней. Диапазон видимых цен 1.6789-1.4567 = 0.2222. 0,2222 / 16 = 0,0138, чтобы я мог показать уровни 1.4716, 1.4854 и т. Д. Но я хочу округлить эти уровни до некоторого значимого числа, например 1.4600, 1.4700, 1.4800 ... или 1.4580, 1.4590, 1.4600 ... или 1.4580, 1.4585 ... и т. Д. Поэтому я хочу всегда показывать как можно больше уровней значимости в зависимости от того, сколько места у меня есть, но всегда показываю только уровни при некоторых значимых значениях (я не говорю, что округленные значения также значимы как 20,25), которые составляют 1, 2, 2,5, 5 и 10 или их множители (10, 20, 25 ... или 100, 200, 250 ... ) или их подразделения (0,1, 0,2, 0,25 ... или 0,0001, 0,0002, 0,00025 ...)
У меня это работает на самом деле, но мне совсем не нравится мой алгоритм, он слишком длинный и не элегантный. Я надеюсь, что кто-то может предложить более элегантный и общий способ. Я ищу алгоритм, я могу реализовать не необходимый код. Ниже мой текущий алогит в объективе-c. Спасибо.
-(float) getPriceLineDenominator
{
NSArray *possVal = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:1.0],
[NSNumber numberWithFloat:2.0],
[NSNumber numberWithFloat:2.5],
[NSNumber numberWithFloat:5.0],
[NSNumber numberWithFloat:10.0],
[NSNumber numberWithFloat:20.0],
[NSNumber numberWithFloat:25.0],
[NSNumber numberWithFloat:50.0],
[NSNumber numberWithFloat:100.0],
nil];
float diff = highestPrice-lowestPrice;//range of shown values
double multiplier = 1;
if(diff<10)
{
while (diff<10)
{
multiplier/=10;
diff = diff*10;
}
}
else
{
while (diff>100)
{
multiplier*=10;
diff = diff/10;
}
}
float result = 0;
for(NSNumber *n in possVal)
{
float f = [n floatValue]*multiplier;
float x = [self priceY:highestPrice];
float y = [self priceY:highestPrice-f];
if((y-x)>=30)//30 is minimum distance between price levels shown
{
result = f;
break;
}
}
return result;
}