Есть ли у кого-нибудь достойный алгоритм расчета минимумов и максимумов осей?
При создании диаграммы для заданного набора элементов данных я хотел бы дать алгоритм:
Алгоритм должен вернуть
Клещи должны быть через равные промежутки времени, должны быть «разумного» размера (например, 1, 3, 5, возможно, даже 2,5, но не больше).
Наличие необязательного значения исказит это, но без этого значения самый большой элемент должен появиться между двумя верхними отметками, а наименьшее значение - между двумя нижними.
Это вопрос, не зависящий от языка, но если бы поблизости была библиотека C# /. NET, это было бы круто;)





Я использовал графическую библиотеку jQuery плавать. Это открытый исходный код, и он неплохо генерирует оси / тики. Я бы посоветовал взглянуть на его код и почерпнуть оттуда некоторые идеи.
Могу порекомендовать следующее:
Это использовалось для приложения, которое позволяло произвольное масштабирование данных и, казалось, работало хорошо.
Хорошо, вот что я придумал для одного из наших приложений. Обратите внимание, что он не имеет отношения к упомянутому вами сценарию «необязательного значения», поскольку наше необязательное значение всегда равно 0, но его не должно быть сложно изменить.
Данные постоянно добавляются в серию, поэтому мы просто обновляем диапазон значений y, проверяя каждую точку данных по мере ее добавления; это очень недорого, и за ним легко следить. Равные минимальные и максимальные значения указаны в специальном регистре: интервал 0 означает, что маркеры рисовать не следует.
Это решение не отличается от предложения Эндрю, приведенного выше, за исключением того, что оно немного запутанно имеет дело с некоторыми произвольными долями множителя экспоненты.
Наконец, этот пример написан на C#. Надеюсь, это поможет.
private float GetYMarkerSpacing()
{
YValueRange range = m_ScrollableCanvas.
TimelineCanvas.DataModel.CurrentYRange;
if ( range.RealMinimum == range.RealMaximum )
{
return 0;
}
float absolute = Math.Max(
Math.Abs( range.RealMinimum ),
Math.Abs( range.RealMaximum ) ),
spacing = 0;
for ( int power = 0; power < 39; ++power )
{
float temp = ( float ) Math.Pow( 10, power );
if ( temp <= absolute )
{
spacing = temp;
}
else if ( temp / 2 <= absolute )
{
spacing = temp / 2;
break;
}
else if ( temp / 2.5 <= absolute )
{
spacing = temp / 2.5F;
break;
}
else if ( temp / 4 <= absolute )
{
spacing = temp / 4;
break;
}
else if ( temp / 5 <= absolute )
{
spacing = temp / 5;
break;
}
else
{
break;
}
}
return spacing;
}
Также см. stackoverflow.com/questions/361681/… и stackoverflow.com/questions/237220/…