2008-09-09 13 views
5

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

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

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

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

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

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

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

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

+0

Также см http://stackoverflow.com/questions/361681/algorithm-for-nice-grid-line-intervals-on-a-graph и http://stackoverflow.com/questions/237220/ tickmark-алгоритм-в-а-граф-оси – 2012-01-05 14:28:46

ответ

0

Я использую библиотеку графа JQuery flot. Это с открытым исходным кодом и отлично подходит для генерации оси/тика. Я бы предложил посмотреть на это код и ущипнуть некоторые идеи оттуда.

0

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

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

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

2

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

 Смежные вопросы

  • Нет связанных вопросов^_^