Frage

Ich bin auf der Suche nach einem „schönen Zahlen“ Algorithmus für die Etiketten auf einem Datum / Zeit-Wert-Achse zu bestimmen. Ich bin vertraut mit Paul Heckbert Nizza Zahlen Algorithmus .

Ich habe eine Handlung, die Zeit / Datum auf der X-Achse und der Benutzer bei einem kleineren Zeit zeigt Zoomrahmen in und aussehen kann. Ich suche nach einem Algorithmus, der schöne Tage, greift die Ticks angezeigt werden soll.

Zum Beispiel:

  • an einem Tag der Suche oder so: 1/1 12:00, 1/1 04.00, 01.01 08.00 Uhr ...
  • Mit Blick auf eine Woche: 1/1, 1/2, 1/3 ...
  • Suchen Sie in einem Monat: 1/09, 2/09, 3/09 ...

Die schöne Etikett Zecken müssen nicht auf den ersten sichtbaren Punkt entsprechen, aber in der Nähe es.

Ist jemand vertraut mit solchen Algorithmus?

War es hilfreich?

Lösung

Der Artikel ‚schöne Zahlen‘ Sie verknüpft erwähnt, dass

  

netteste Zahlen in dezimaler sind 1, 2, 5 und alles Zweierpotenz-Vielfachen 10 dieser Zahlen

Also ich denke, für Sie etwas ähnliches mit Datum / Zeit tun müssen, indem in ähnlicher Weise den Abbau der Teilstücke starten. So nehmen Sie die schönen Faktoren jede Art von Intervall:

  • Wenn Sie zeigt Sekunden oder Minuten verwenden 1, 2, 3, 5, 10, 15, 30 (I übersprungenen 6, 12, 15, 20, weil sie "fühlen" nicht rechts).
  • Wenn Sie zeigt Stunden verwenden 1, 2, 3, 4, 6, 8, 12
  • für Tag benutzen 1, 2, 7
  • für Wochen verwenden 1, 2, 4 (13 und 26 das Modell passen scheinen aber auch seltsam für mich)
  • für Monate verwenden 1, 2, 3, 4, 6
  • jahrelang verwenden 1, 2, 5 und Power-of-10 Multiples

Jetzt offensichtlich beginnt diese, wie Sie in größeren Mengen erhalten zu brechen. Sicherlich mögen Sie nicht tun, 5 Wochen zeigen im Wert von Minuten, auch in „ziemlich“ Intervallen von 30 Minuten oder so. Auf der anderen Seite, wenn Sie nur noch 48 Stunden im Wert haben, wollen Sie nicht mindestens 1 Tag Intervalle zeigen. Der Trick, wie Sie haben bereits darauf hingewiesen, ist anständig Übergangspunkte zu finden.

Nur auf einer Ahnung, würde ich sagen, ein vernünftiger Kreuzungspunkt etwa doppelt so viel wie das nächste Intervall sei. Das würde Ihnen die folgende (min und max Anzahl der Intervalle danach gezeigt)

  • Verwendung Sekunden, wenn Sie weniger als 2 Minuten im Wert (1-120)
  • Verwendung Minuten, wenn Sie weniger als 2 Stunden im Wert (2-120)
  • Nutzung Stunden, wenn Sie weniger als 2 Tage im Wert (2-48)
  • verwenden Tage, wenn Sie weniger als 2 Wochen im Wert von (2-14)
  • Verwendung Wochen, wenn Sie weniger als 2 Monate im Wert (2-8 / 9)
  • Verwendung Monate, wenn Sie weniger als 2 Jahre im Wert (2-24)
  • sonst verwenden Jahre (obwohl Sie mit Jahrzehnte fortsetzen konnte, Jahrhunderte, etc, wenn Ihre Bereiche so lange sein kann)

Leider ist unsere inkonsistente Zeitintervalle bedeuten, dass Sie mit einigen Fällen enden, die haben über 1 hundert Intervalle können, während andere höchstens 8 oder 9 haben, so wollen Sie die Größe Ihrer Intervalle wählen so, als Sie don‘ t hat mehr als 10-15 Intervalle höchstens (oder weniger als 5 in diesem Fall). Auch könnten Sie von einer genauen Definition von 2-mal das nächsten größten Intervall brechen, wenn Sie seine leicht denken, im Auge zu behalten. Zum Beispiel könnte man Stunden bis zu 3 Tagen (72 Stunden) und Wochen bis zu 4 Monaten verwenden. Ein wenig Versuch und Irrtum notwendig sein könnten.

So über zurück zu gehen, wählen Sie den Intervalltyp auf der Grundlage der Größe des Bereichs, dann wählen Sie die Intervallgröße von einem der „schönen“ Zahlen Kommissionierung, die Sie mit zwischen 5 und 15 Teilstriche hinterlassen. Oder wenn Sie wissen, und / oder kann die tatsächliche Anzahl der Pixel zwischen tick Kontrollmarkierungen können Sie obere und untere Grenze auf setzen, wie viele Pixel sind akzeptabel zwischen Zecken (wenn sie angeordnet sind zu weit voneinander entfernt die grafische Darstellung kann schwierig sein, zu lesen, aber wenn es zu viele Zecken die Grafik überladen sein und Ihre Etiketten können sich überlappen).

Andere Tipps

Immer noch keine Antwort auf diese Frage ... Ich werde meine erste Idee in dann werfen! Ich gehe davon aus Sie den Bereich des sichtbaren Achse haben.

Dies ist wahrscheinlich, wie ich tun würde.

Raue pseudo:

// quantify range
rangeLength = endOfVisiblePart - startOfVisiblePart;

// qualify range resolution
if (range < "1.5 day") {
    resolution = "day";  // it can be a number, e.g.: ..., 3 for day, 4 for week, ...
} else if (range < "9 days") {
    resolution = "week";
} else if (range < "35 days") {
    resolution = "month";
} // you can expand this in both ways to get from nanoseconds to geological eras if you wish

Danach sollte es (je nachdem, was Sie eine einfachen Zugang zu haben) seine ganz leicht, den Wert zu jedem schönen Etikett tick zu bestimmen. In Abhängigkeit von der ‚Auflösung‘, können Sie es anders formatiert werden. Z.B .: MM / DD für "Woche", MM: SS. Für "Minute" usw., so wie du gesagt

Haben Sie einen Blick auf

http://tools.netsa.cert.org/netsa -python / doc / index.html

Es hat eine nice.py (Python / netsa / data / nice.py), die ich denke, ist eigenständig, und sollte gut funktionieren.

Ich würde vorschlagen, dass Sie den Quellcode greifen gnuplot oder RRDTool (oder sogar Flot) und untersucht, wie sie dieses Problem angehen. Der allgemeine Fall ist wahrscheinlich N Etikett aufgebracht werden, basierend auf Breite der Handlung, die eine Art ‚Schnappen‘ zur nächsten ‚nett‘ Nummer.

Jedes Mal, wenn ich einen solchen Algorithmus geschrieben habe (zu oft wirklich), habe ich eine Tabelle von ‚Einstellungen‘ verwendet ... das heißt: auf der Grundlage der Zeitbereich auf dem Grundstück, entscheiden, ob ich Wochen bin mit , Tage, Stunden, Minuten usw. als Hauptachsenpunkt. I enthalten in der Regel eine bevorzugte Formatierung, wie ich selten das Datum für jede Minute, die ich Grundstück auf dem Diagramm angezeigt werden sollen.

Ich würde gerne, aber überrascht, jemanden zu finden, mit einer Formel (wie Heckbert tut) ‚nett‘, wie die Veränderung der Zeiteinheiten zwischen Minuten, Stunden, Tagen und Wochen zu finden ist nicht linear.

[Bearbeiten - ich erweiterte diese ein wenig mehr unter http://www.acooke.org /cute/AutoScalin0.html ]

Eine naive Erweiterung des „schöne Zahlen“ Algorithmus scheint für die Basis 12 und 60, die für Stunden und Minuten gut Abstände gibt zu arbeiten. Dies ist Code, den ich gerade gehackt zusammen:

LIM10 = (10, [(1.5, 1), (3, 2), (7, 5)], [1, 2, 5])
LIM12 = (12, [(1.5, 1), (3, 2), (8, 6)], [1, 2, 6])
LIM60 = (60, [(1.5, 1), (20, 15), (40, 30)], [1, 15, 40])


def heckbert_d(lo, hi, ntick=5, limits=None):
    '''
    Heckbert's "nice numbers" algorithm for graph ranges, from "Graphics Gems".
    '''
    if limits is None:
        limits = LIM10
    (base, rfs, fs) = limits
    def nicenum(x, round):
        step = base ** floor(log(x)/log(base))
        f = float(x) / step
        nf = base
        if round:
            for (a, b) in rfs:
                if f < a:
                    nf = b
                    break
        else:
            for a in fs:
                if f <= a:
                    nf = a
                    break
        return nf * step
    delta = nicenum(hi-lo, False)
    return nicenum(delta / (ntick-1), True)


def heckbert(lo, hi, ntick=5, limits=None):
    '''
    Heckbert's "nice numbers" algorithm for graph ranges, from "Graphics Gems".
    '''
    def _heckbert():
        d = heckbert_d(lo, hi, ntick=ntick, limits=limits)
        graphlo = floor(lo / d) * d
        graphhi = ceil(hi / d) * d
        fmt = '%' + '.%df' %  max(-floor(log10(d)), 0)
        value = graphlo
        while value < graphhi + 0.5*d:
            yield fmt % value
            value += d
    return list(_heckbert())

So zum Beispiel, wenn Sie Sekunden von 0 bis 60 angezeigt werden sollen,

>>> heckbert(0, 60, limits=LIM60)
['0', '15', '30', '45', '60']

oder Stunden von 0 bis 5:

>>> heckbert(0, 5, limits=LIM12)
['0', '2', '4', '6']

In der Theorie können Sie auch Ihr Konzept ändern. Wo es nicht Ihre Daten in der Mitte der Visualisierung ist, aber in der Mitte haben Sie Ihre Waage.

Wenn Sie den Anfang und das Ende der Daten Ihrer Daten kennen, können Sie eine Skala mit allen Terminen erstellen und versenden Sie Daten in dieser Größenordnung. Wie eine feste Skalen.

Sie können eine Skala von Typ Jahr, Monat, Tag, Stunden, ... und die Skalierung begrenzen nur diese Skalen, Sie entfernen das Konzept der freien Skalierung impliziert.

Der Vorteil ist, kann leicht Termine Lücken zeigen. Aber wenn Sie eine Menge Lücken haben, kann man erkennen, werden auch nutzlos.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top