График (Chart) Алгоритм - PullRequest
       17

График (Chart) Алгоритм

5 голосов
/ 09 сентября 2008

У кого-нибудь есть приличный алгоритм для расчета минимумов и максимумов осей?

При создании диаграммы для заданного набора элементов данных я бы хотел иметь алгоритм:

  • максимальное значение (y) в наборе
  • минимальное (y) значение в наборе
  • количество отметок на оси
  • необязательное значение, которое должно отображаться в виде галочки (например, ноль при отображении значений + ve и -ve)

алгоритм должен вернуть

  • наибольшее значение оси
  • наименьшее значение оси (хотя оно может быть выведено из наибольшего значения, размера интервала и числа тиков)
  • размер интервала

Клещи должны быть через регулярные промежутки времени должны иметь «разумный» размер (например, 1, 3, 5, возможно, даже 2,5, но не более фиг.).

Наличие необязательного значения искажает это, но без этого значения самый большой элемент должен появляться между двумя верхними отметками, а самое низкое значение - между двумя нижними.

Это вопрос, не зависящий от языка, но если вокруг будет библиотека C # / .NET, это будет громким;)

Ответы [ 3 ]

2 голосов
/ 30 сентября 2008

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

Я могу порекомендовать следующее:

  • Установите визуально привлекательное минимальное количество основных линий. Это будет зависеть от характера данных, которые вы предоставляете, и размера графика, который вы делаете, но 7 - довольно хорошее число
  • Выберите показатель степени и множитель, основанный на прогрессии 1, 2, 5, 10 и т. Д., Что даст вам как минимум минимальное количество основных линий. (т. е. (макс-мин) / (масштаб х 10 ^ экспонента)> = минимальная_имень_марков)
  • Найдите минимальное целое число, кратное вашему показателю степени и множителю, которое соответствует вашему диапазону. Это будет первая серьезная галочка. Остальные клещи являются производными от этого.

Это использовалось для приложения, которое допускало произвольное масштабирование данных и, казалось, работало хорошо.

0 голосов
/ 09 сентября 2008

Я использую библиотеку графов jQuery flot . Это открытый исходный код и довольно хорошо выполняет генерацию осей / тиков. Я бы посоветовал взглянуть на его код и оттуда извлечь некоторые идеи.

...