2008-09-09 22 views
5

Czy ktoś ma przyzwoity algorytm do obliczania minimów i maksimów osi?Wykres (wykres) Algorytm

Tworząc wykres dla danego zbioru elementów danych, to, że jak się w stanie dać algorytmu:

  • wartość maksymalną (T) w zestawie
  • minimum (y) wartość w zbiorze
  • liczba znacznikami pojawiać na osi
  • wartość opcjonalna, musi pojawiają się kleszcza (np zero, gdy pokazano dodatniej i ujemnej wartości)

algorytm powinien wrócić

  • największą wartość osi
  • najmniejszą wartość osi (chociaż mogą być wywnioskowane z najdłuższych przedziału wielkości i numer kleszczy)
  • przedziału wielkości

Kleszcze powinny mieć regularny odstęp od "rozsądnego" rozmiaru (np. 1, 3, 5, być może nawet 2,5, ale już nie więcej sig).

Obecność wartości opcjonalnej będzie przekrzywiona, ale bez tej wartości największy element powinien pojawić się między dwoma górnymi znacznikami, najniższa wartość między dwoma dolnymi.

Jest to kwestia języka agnostykiem, ale jeśli istnieje C#/.NET biblioteki wokół, że będzie rozbijając;).

+0

Zobacz także http://stackoverflow.com/questions/361681/algorithm-for-nice-grid-line-intervals-on-a-graph i http://stackoverflow.com/questions/237220/ tickmark-algorithm-for-a-graph-axis –

Odpowiedz

0

Używam wykres biblioteki jQuery flot. Jest open source i całkiem dobrze generuje oś/tick. Sugerowałbym przeglądnięcie kodu i zbieranie pomysłów.

0

mogę polecić następujące:

  • Ustaw wizualnie minimalną liczbę głównych linii. Będzie to zależało od charakteru prezentowanych danych i wielkości działki, ale 7 to całkiem niezły numer.
  • Wybierz wykładnik i mnożnik w oparciu o 1, 2, 5, 10 itd., Która da ci co najmniej minimalną liczbę głównych linii. (maks. min)/(skala x 10^wykładnik)> = minimum_tick_marks)
  • Znajdź minimalną wielokrotność całkowitą twojego wykładnika i mnożnika, która mieści się w twoim zakresie. To będzie pierwszy duży tyk. Reszta kleszczy pochodzi z tego.

Zostało to wykorzystane w przypadku aplikacji, która pozwalała na arbitralne skalowanie danych i wydawało się, że działa dobrze.

2

OK, oto, co wymyśliłem dla jednej z naszych aplikacji. Zwróć uwagę, że nie dotyczy on scenariusza "opcjonalnej wartości", o którym wspomniałeś, ponieważ nasza opcjonalna wartość to zawsze 0, ale modyfikacja nie powinna być dla Ciebie trudna.

Dane są nieustannie dodawane do serii, więc po prostu przechowujemy zakres wartości y, sprawdzając każdy punkt danych jako dodany; jest to bardzo tanie i łatwe do śledzenia.Równe minimalne i maksymalne wartości są przypadkami specjalnymi: odstęp 0 wskazuje, że nie należy narysować znaczników.

Rozwiązanie to nie różni się od sugestii Andrew powyżej, z tym, że zajmuje się w sposób mało kruchy z dowolnymi częściami mnożnika wykładniczego.

Wreszcie ta próbka jest w języku C#. Mam nadzieję, że to pomoże.

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; 
    }