Ankündigung

Einklappen
Keine Ankündigung bisher.

Tag Cloud: Algorithmus für Schriftgröße

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Tag Cloud: Algorithmus für Schriftgröße

    [edit]
    Die fertige PHP Klasse gibts mittlerweile unter folgender Adresse:
    http://simbo.de/blog/code/php-klasse-tagcloud/
    [/edit]

    Servus miteinander...

    ich arbeite gerade an einer PHP Klasse, die anhand eines Arrays mit Tags und deren Häufigkeit eine Tag-Cloud erstellen soll.

    Die minimale und maximale Schriftgröße sollen frei wählbar sein, ebenso die Einheit (px, pt, oder em).

    Als Formel zur Berechnung der Schriftgröße hab ich zuerst die bei Wikipedia genannte Formel verwendet.
    http://de.wikipedia.org/wiki/Tag_cloud

    Mit dem Ergebnis bin ich aber sehr unzufrieden. Ich hätte gerne "weichere Abstufungen".

    Ich hab auf dieser Seite eine Beschreibung für eine "Logarithmische Verteilung der Schriftgrößen" gefunden:
    http://www.echochamberproject.com/node/247

    Die Graphen dort sehen vielversprechend aus, und ich würde gerne dieselbe Formel verwenden.
    Leider komme ich aber mit der Beschreibung dort überhaupt nicht zurecht... und Drupal kann ich nicht...

    Kann mir jemand diese Logarithmische Drupal-Formel in PHP übersetzen?
    Oder mir zumindest mal in verständlicher Form sagen, wie diese Formel aussieht...

    Meine Funktion zur Berechnung der Schriftgröße sieht derzeit so aus:

    Code:
    function TagCloudFontsizeDistribution( $count, $mincount, $maxcount, $minsize, $maxsize ) {
      $s = ( ( ($maxsize-$minsize)*($count-$mincount) ) / ( $maxcount-$mincount ) ) + $minsize;
      return round($s,0);
    }

    Gruß,

    Simon

  • #2
    unabhängig von der verlinkten Formel, schau Dir einfach mal die Logarithmuskurve an: http://de.wikipedia.org/wiki/Bild:Log4.png

    Benutze f = logn(x) mit n>1, begrenze Minimum und Maximum von y mit php's min () und max () Funktionen. Jetzt brauchst Du nur noch die auftretenden Werte linear auf einen bestimmten, begrenzten x Bereich abbilden. Sollte zu schaffen sein.

    Kommentar


    • #3
      Hmm...

      ...ich hab jedenfalls ne Lösung...

      Kevin Hoffmann's Whitepaper "In Search of the perfect Tag Cloud" hat mir dabei sehr geholfen.
      Wen's interessiert: http://dotnetaddict.dotnetdevelopersjournal.com/tw.htm

      Die dort beschriebene Funktion ist im Grunde genau dieselbe wie auf der Seite des EchoChamberProjects, aber nicht in Pseudo-Programmiersprache...

      Wie auch immer... ich hab sie in PHP übersetzt und dabei ziemlich gekürzt...

      Am Ende kam das dabei raus:

      Code:
      function GetTagSizeLogarithmic( $count, $mincount, $maxcount, $minsize, $maxsize ) {
          $steps = $maxsize-$minsize;
          $delta = ($maxcount-$mincount)/$steps;
          while( log($count+2)>log($mincount+$a*$delta+2) && $a<$steps ) $a++;
          return $minsize+$a;
        }
      Funktioniert perfekt...

      Falls einer von euch mal in irgendeiner Form ne Tag-Cloud machen will, viel Spaß damit...
      Die Funktion lässt sich auch z.B. für Farbwerte verwenden.

      Gruß

      Simon

      Kommentar


      • #4
        Hi

        ermittel doch den/die Tag/s die am häufigsten vorkommen. Bei allen Tags die darunter liegen ermittelst du den prozentualen Anteil verglichen mit den häufigsten Tags.

        Hase: 100 mal
        Katze 20 mal
        Vogel: 3 mal

        Katze würde 20 % und Vogel 3 % entsprechen. Jetzt kannst du das mal einem beliebigen Faktor nehmen, um deine Schriftgröße zu ermitteln. Zum Beispiel mit 1. Dann wäre Hase 100px, Katze 20px und Vogel 3px groß.

        Kommentar


        • #5
          So einfach ist es nun auch nicht...

          Die Logarithmische Verteilung der Schriftgrößen bietet eine viel effizientere Darstellung der Tag-Gewichtung als die lineare, die du beschreibst...

          Anders gesagt "verfälscht" die lineare Darstellung sogar die Tag-Gewichtung.

          Wer mehr wissen will, soll sich die oben verlinkten Seiten ansehen und googeln...

          Kommentar


          • #6
            Zitat von Simbo
            Am Ende kam das dabei raus:

            Code:
            function GetTagSizeLogarithmic( $count, $mincount, $maxcount, $minsize, $maxsize ) {
                $steps = $maxsize-$minsize;
                $delta = ($maxcount-$mincount)/$steps;
                while( log($count+2)>log($mincount+$a*$delta+2) && $a<$steps ) $a++;
                return $minsize+$a;
              }
            Ist es wirklich sinnvoll, in die Funktion ne Schleife einzubauen? Die dazu auch noch 2 Logarithmen pro Schleifendurchlauf errechnet? Das muß doch auch rein mathematisch mit einer Funktion, norfalls noch mit Trinäroperator und php's max und min möglich sein.
            Notfalls würde ich zumindest nicht jede Größe extra berechnen, sondern ein Array erstellen, das gestaffelt bestimmte Größenbereiche enthält. Angaben wie 1.023 em und 1.0421 em werden sich objektiv ohnehin nicht unterscheiden. Es sei denn, Du zoomtest die Seite auf 1000% oder so.
            .

            Kommentar


            • #7
              jo... mittlerweile hat sich die Funktion auch ein wenig weiterentwickelt...

              Nachdem ich ein bißchen damit rumgespielt hab, stellte ich fest, dass ein fließender Übergang von z.B. 10-24px in 1px-Schritten den Nachteil hat, dass man nicht mehr klar unterscheiden kann, welche Tags nun wie stark gewertet wurden.
              Also mussten unabhängig von den festgelegten Schriftgrößen Grenzbereiche her.
              Bei 10-24px also 8 Schriftarten, 7 Schritte à 2px.

              Den Algorithmus mit der Schleife und den natürlichen Logarithmen hatte ich wie gesagt von Kentbye's Artikel http://www.echochamberproject.com/node/247. Das klang auch alles ganz plausibel (schöne Diagramme ) allerdings hab ich den Pseudo-Code dort nicht richtig verstanden.
              Dann fand ich http://www.car-chase.net/2007/jan/16...clouds-python/ und http://files.blog-city.com/files/J05...cttagcloud.pdf die meiner Meinung nach von Kentbye abgeschrieben haben aber den Code für mich verständlicher präsentierten.

              Zum Testen hab ich den den Datensatz von Kentbye's Seite genommen. Jedoch kam ich nie auf das gewünschte Ergebnis. Die Tag-Cloud veränderte sich nur minimal im Vergleich zur linearen Funktion.
              Und mit meinen Tags von del.icio.us konnte ich auch nicht dieselbe Tag-Cloud wie auf der del.icio.us-Seite anzeigen lassen - die Schritftgrößenverteilung hat einfach nicht gestimmt.

              Dann hab ich http://blogoforum.com/tag/blogoforum...nued-3294.html gefunden und das hats letztendlich gebracht.
              Komischerweise konnte ich mit dieser Formel nicht nur die del.icio.us TagCloud nachbilden sondern auch die von Kentbye angeblich mit seiner Formel erstellten Wolke.

              Und wie ihr seht ohne Schleife:

              PHP-Code:
                function GetTagSizeLogarithmic$count$mincount$maxcount$minsize$maxsize$tresholds ) {
                  if( empty(
              $tresholds) ) :
                    
              $tresholds $maxsize-$minsize;
                    
              $treshold 1;
                  else :
                    
              $treshold = ($maxsize-$minsize)/($tresholds-1);
                  endif;
                  
              $a $tresholds*log($count $mincount+2)/log($maxcount $mincount+2)-1;
                  return 
              round($minsize+round($a)*$treshold);
                } 

              Kommentar


              • #8
                Na siehste. Optimal wäre jetzt noch eine Art Caching, also das Vorhalten der bereits errechneten Werte in einem Array, um zu verhindern, dass für identische Ausgangswerte jeweils die aufwendige Berechnung neu gestartet werden muß.

                Kommentar


                • #9
                  Da die Funktion sowieso Teil einer Klasse ist, wäre es kein Problem jeden bereits errechneten Wert für $count in ein Array zu pushen.

                  Aber ist das wirklich nötig?
                  Ich mein, kann man bei so zwei kleinen Logarithmen bereits von aufwändiger Berechnung sprechen?
                  Darf ich einem DualCore-CPU nur Addition/Subtraktion zum Rechnen geben weil er für alles andere zu lange braucht?

                  Kommentar


                  • #10
                    Kommt darauf an, wie groß die Wolke so wird, wa? Der Logarithmus ist nicht gerade die trivialste Rechenart.

                    Fällt mir gerade auf:
                    PHP-Code:
                    <?
                        if( empty($tresholds) ) :
                          $tresholds = $maxsize-$minsize;
                          $treshold = 1;
                        else :
                          $treshold = ($maxsize-$minsize)/($tresholds-1);
                        endif;
                    Mal überlegt, was passiert, wenn $tresholds == 1 ist?

                    Kommentar


                    • #11
                      Naja, so ne Wolke wird irgendwann unübersichtlich.
                      100 Tags sind wohl das Maximum...

                      Aber so ein "cache" ist auf jeden Fall ein Pluspunkt und ich hab das mal in die Funktion eingebaut, die GetTagSizeLogarithmic() aufruft.

                      Danke für den Hinweis!

                      Kommentar


                      • #12
                        Bitte schau Dir nochmal mein erweitertes Posting von eben an.

                        Kommentar


                        • #13
                          Mal überlegt, was passiert, wenn $tresholds == 1 ist?
                          oh, hehe...

                          ich tausch mal
                          Code:
                          if( empty($tresholds) )
                          gegen
                          Code:
                          if( !is_int($tresholds) || $tresholds<2 )
                          ...


                          nochmals, danke

                          Kommentar


                          • #14
                            Hi,

                            ich habe mit deinem Quelltext ein bisschen gespielt, aber mir ist nicht klar, wo für die Variable $tresholds ist, die du der Funktion übergibst.

                            mfg
                            Muad

                            Kommentar


                            • #15
                              Gut, dass Du den Thread nochmal rausgekramt hast. Ist ja erst ein Jahr alt...

                              Kommentar

                              Lädt...
                              X