Was ist der beste Weg, um eine Tag-Cloud aus einem Array mit h1 bis h6 für die Größenbestimmung zu generieren?

75

Ich habe die folgenden Arrays:

$artist = array("the roots", "michael jackson", "billy idol", "more", "and more", "and_YET_MORE");
$count = array(5, 3, 9, 1, 1, 3);

Ich möchte eine Tag-Cloud generieren, die Künstler mit einer höheren Anzahl in $counteingeschlossenen h6Tags und den niedrigsten eingeschlossenen h1Tags enthält.

w-ll
quelle

Antworten:

40

Sie möchten auch eine logarithmische Funktion hinzufügen. (entnommen aus tagadelic, meinem Drupal-Modul zum Erstellen von Tag-Clouds http://drupal.org/project/tagadelic ):

db_query('SELECT COUNT(*) AS count, id, name FROM ... ORDER BY count DESC');

$steps = 6;
$tags = array();
$min = 1e9;
$max = -1e9;

while ($tag = db_fetch_object($result)) {
    $tag->number_of_posts = $tag->count; #sets the amount of items a certain tag has attached to it
    $tag->count = log($tag->count);
    $min = min($min, $tag->count);
    $max = max($max, $tag->count);
    $tags[$tag->tid] = $tag;
}
// Note: we need to ensure the range is slightly too large to make sure even
// the largest element is rounded down.
$range = max(.01, $max - $min) * 1.0001;

foreach ($tags as $key => $value) {
    $tags[$key]->weight = 1 + floor($steps * ($value->count - $min) / $range);
}

Dann in Ihrer Ansicht oder Vorlage:

foreach ($tags as $tag) {
    $output .= "<h$tag->weight>$tag->name</h$tag->weight>"
}
berkes
quelle
30

Aus dem Kopf ...

$artist = array("the roots","michael jackson","billy idol","more","and more","and_YET_MORE");
$count = array(5,3,9,1,1,3);
$highest = max($count);
for (int $x = 0; $x < count($artist); $x++)
{
    $normalized = $count[$x] / $highest;
    $heading = ceil($normalized * 6); // 6 heading types
    echo "<h".$heading.">".$artist[$x]."</h".$heading.">";
}
Ryan Fox
quelle
24

Vielleicht ist dies ein wenig akademisch und nicht thematisch, aber hXTags sind aus Gründen der Dokumentstruktur und dergleichen wahrscheinlich nicht die beste Wahl für eine Tag-Cloud.

Vielleicht spans oder a olmit entsprechenden Klassenattributen (plus etwas CSS)?

Brendan
quelle
8

Habe dieses Snippet eine Weile benutzt, Kredit ist prism-perfect.net. Verwendet jedoch keine H-Tags

<div id="tags">
    <div class="title">Popular Searches</div>
    <?php
        // Snippet taken from [prism-perfect.net]

        include "/path/to/public_html/search/settings/database.php";
        include "/path/to/public_html/search/settings/conf.php";

        $query = "SELECT query AS tag, COUNT(*) AS quantity
        FROM sphider_query_log
        WHERE results > 0
        GROUP BY query
        ORDER BY query ASC
        LIMIT 10";

        $result = mysql_query($query) or die(mysql_error());

        while ($row = mysql_fetch_array($result)) {

            $tags[$row['tag']] = $row['quantity'];
        }

        // change these font sizes if you will
        $max_size = 30; // max font size in %
        $min_size = 11; // min font size in %

        // get the largest and smallest array values
        $max_qty = max(array_values($tags));
        $min_qty = min(array_values($tags));

        // find the range of values
        $spread = $max_qty - $min_qty;
        if (0 == $spread) { // we don't want to divide by zero
            $spread = 1;
        }

        // determine the font-size increment
        // this is the increase per tag quantity (times used)
        $step = ($max_size - $min_size)/($spread);

        // loop through our tag array
        foreach ($tags as $key => $value) {

            // calculate CSS font-size
            // find the $value in excess of $min_qty
            // multiply by the font-size increment ($size)
            // and add the $min_size set above
            $size = $min_size + (($value - $min_qty) * $step);
            // uncomment if you want sizes in whole %:
            // $size = ceil($size);

            // you'll need to put the link destination in place of the /search/search.php...
            // (assuming your tag links to some sort of details page)
            echo '<a href="https://stackoverflow.com/search/search.php?query='.$key.'&search=1" style="font-size: '.$size.'px"';
            // perhaps adjust this title attribute for the things that are tagged
            echo ' title="'.$value.' things tagged with '.$key.'"';
            echo '>'.$key.'</a> ';
            // notice the space at the end of the link
        }
    ?>
</div>
Konrad Krakowiak
quelle
Dies scheint mir ein guter Ansatz zu sein. Wenn sich Ihre Daten in einem Array befinden, überspringen Sie einfach den Datenbankteil. Ich würde empfehlen, dass Sie den Künstlernamen und die Anzahl in einem einzigen assoziativen Array speichern. Um dies mit dem obigen Code zu ermöglichen, verwenden Sie Folgendes: $ tags = array ("die Wurzeln" => 5, "michael jackson" = 3, "billy idol" => 9, "madonna" => 1); Ich würde zustimmen, keine H-Tags zu verwenden, da dies Ihre Semantik durcheinander bringt. Spannweiten wären meine Wahl. Schließlich gibt es in Zend Framework einen Helfer, der genau das tut, was Sie brauchen. Siehe framework.zend.com/manual/en/zend.tag.html
simonrjones
6

@ Ryan

Das ist richtig, aber es macht die Tags mit der geringsten Anzahl tatsächlich größer. Dieser Code wurde getestet:

$artist = array("the roots","michael jackson","billy idol","more","and more","and_YET_MORE");
$count = array(5,3,9,1,1,3);
$highest = max($count);
for ($x = 0; $x < count($artist); $x++) {
    $normalized =  ($highest - $count[$x]+1) / $highest;
    $heading = ceil($normalized * 6); // 6 heading types
    echo "<h$heading>{$artist[$x]}</h$heading>";
}
Kevin
quelle
2

Diese Methode ist für SQL/PostgreSQLFanatiker. Es erledigt den gesamten Job in der Datenbank und druckt Text mit dem Link "Slugified". Es verwendet Doctrine ORMnur für den SQL-Aufruf, ich verwende keine Objekte. Angenommen, wir haben 10 Größen:

public function getAllForTagCloud($fontSizes = 10)
{
    $sql = sprintf("SELECT count(tag) as tagcount,tag,slug, 
    floor((count(*) * %d )/(select max(t) from 
        (select count(tag) as t from magazine_tag group by tag) t)::numeric(6,2)) 
         as ranking 
         from magazine_tag mt group by tag,slug", $fontSizes);

    $q = Doctrine_Manager::getInstance()->getCurrentConnection();
    return $q->execute($sql);
}

Dann drucken Sie sie mit einer CSS-Klasse, von .tagranking10 (die beste) bis .tagranking1 (die schlechteste):

<?php foreach ($allTags as $tag): ?>
    <span class="<?php echo 'tagrank'.$tag['ranking'] ?>">
        <?php echo sprintf('<a rel="tag" href="/search/by/tag/%s">%s</a>', 
            $tag['slug'], $tag['tag']
        ); ?>
    </span>
<?php endforeach; ?>

und das ist das CSS:

/* put your size of choice */
.tagrank1{font-size: 0.3em;}
.tagrank2{font-size: 0.4em;}
.tagrank3{font-size: 0.5em;} 
/* go on till tagrank10 */

Diese Methode zeigt alle Tags an. Wenn Sie viele davon haben, möchten Sie wahrscheinlich nicht, dass Ihre Tag-Cloud zu einem Tag-Sturm wird . In diesem Fall würden Sie HAVING TOIhrer SQL-Abfrage eine Klausel hinzufügen:

-- minimum tag count is 8 --

HAVING count(tag) > 7

Das ist alles

Danieli
quelle
1

Als Helfer in Rails:

def tag_cloud (strings, counts)
    max = counts.max
    strings.map { |a| "<span style='font-size:#{((counts[strings.index(a)] * 4.0)/max).ceil}em'>#{a}</span> "  }
end

Nennen Sie dies aus der Sicht:

<%= tag_cloud($artists, $counts) %>

Dies gibt <span style='font-size:_em'>Elemente in einem Array aus, die in der Ansicht in eine Zeichenfolge konvertiert werden, um letztendlich wie folgt zu rendern:

<span style='font-size:3em'>the roots</span>
<span style='font-size:2em'>michael jackson</span> 
<span style='font-size:4em'>billy idol</span> 
<span style='font-size:1em'>more</span> 
<span style='font-size:1em'>and more</span> 
<span style='font-size:2em'>and_YET_MORE</span> 

Es wäre besser, ein classAttribut zu haben und die Klassen in einem Stylesheet zu referenzieren, wie oben von Brendan erwähnt. Viel besser als h1-h6semantisch zu verwenden und es gibt weniger Stilgepäck mit einem <span>.

Aminah Nuraini
quelle
Warum hat jemand eine -1 gegeben?
Berkeley
0

Ich weiß, dass es ein sehr alter Beitrag ist, aber ich poste immer noch meine Ansicht, da sie in Zukunft jemandem helfen könnte.

Hier ist die Tagcloud, die ich auf meiner Website verwendet habe: http://www.vbausefulcodes.in/

<?php
$input= array("vba","macros","excel","outlook","powerpoint","access","database","interview questions","sendkeys","word","excel projects","visual basic projects","excel vba","macro","excel visual basic","tutorial","programming","learn macros","vba examples");

$rand_tags = array_rand($input, 5);
for ($x = 0; $x <= 4; $x++) {
    $size = rand ( 1 , 4 );
    echo "<font size='$size'>" . $input[$rand_tags[$x]] . " " . "</font>";
}

echo "<br>";
$rand_tags = array_rand($input, 7);
for ($x = 0; $x <= 6; $x++) {
    $size = rand ( 1 , 4 );
    echo "<font size='$size'>" . $input[$rand_tags[$x]] . " " . "</font>";
}

echo "<br>";
$rand_tags = array_rand($input, 5);
for ($x = 0; $x <= 4; $x++) {
    $size = rand ( 1 , 4 );
    echo "<font size='$size'>" . $input[$rand_tags[$x]] . " " . "</font>";
}
?>
Durgaprasad
quelle