ОК, вот что я придумал для одного из наших приложений. Обратите внимание, что он не имеет отношения к сценарию «необязательного значения», о котором вы упомянули, поскольку наше необязательное значение всегда равно 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;
}