Вопрос

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

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

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

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

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

Тики должны располагаться через равные промежутки времени и иметь «разумный» размер (например,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;
    }

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top