Облако тегов

Сегодня будем рассматривать такую задачку как генерация облака тегов. Мы все конечно ни раз встречали это облако на других сайтах и блогах, но не все задумывались над реализацией этого облака на php. Общие моменты ясны из определения с wiki:

“визуальное представление списка ярлыков (или категорий). Частота упоминаний, поисков, ссылок в интернете с определенного сайта неких слов, терминов, имен, отображается на специальной странице в виде изображения этих слов в формате гиперссылок. Размер изображения тем больше, чем выше релевантность данного слова (термина, имени).”

Релевантность в нашем случае определяется количеством вхождений одного тега в их общую массу.

Учитывая все вышесказанное, весь алгоритм построения облака тегов можно разделить на два этапа:

  1. Генерация списка пар Тег-Количество вхождений
  2. Вывод облака с учетом релевантности тегов

Первая задача решается довольно просто с технической точки зрения. Вторая тоже, но здесь возможны вариации.

Ниже приведу небольшой класс, который я написал для генерации облака тегов.

<?
class TagsCloud {
	private $tags;
	private $font_size_min = 14;
	private $font_size_step = 5;
	function __construct($tags) {
		shuffle($tags);
		$this->tags = $tags;	
	}
	private function get_tag_count($tag_name, $tags) {
		$count = 0;
		foreach ($tags as $tag) {
			if ($tag == $tag_name) {
				$count++;
			}
		}
		return $count;
	}
	private function tagscloud($tags) {
		$tags_list = array();
		foreach ($tags as $tag) {
			$tags_list[$tag] = self::get_tag_count($tag, $tags);
		}
		return $tags_list;		
	}
	private function get_min_count($tags_list) {
		$min = $tags_list[$this->tags[0]];
		foreach ($tags_list as $tag_count) {
			if ($tag_count < $min) $min = $tag_count;
		}
		return $min;
	}
	public function get_cloud() {
		$cloud = Array();
		$tags_list = self::tagscloud($this->tags);
		$min_count = self::get_min_count($tags_list);
		foreach ($tags_list as $tag=>$count) {
			$font_steps = $count - $min_count;
			$font_size = $this->font_size_min + $this->font_size_step * $font_steps;
			$cloud[] = "<span style='font-size:".$font_size."px'>".$tag."</span>";
		}
		return $cloud;
	}
}
?>

Скачать этот класс можно здесь: tagscloud.php, а работать с этим классом примерно так:

<?
$tags = array(
	'ajax', 'javascript', 'php', 'dojo',
	'ajax', 'jquery', 'seo', 'seo',
	'php', 'blog', 'ajax', 'php',
	'html', 'css', 'ajax', 'javascript',
	'css', 'jquery', 'php', 'smo'
);
$mycloud   = new TagsCloud($tags);
$tags_list = $mycloud->get_cloud();
foreach ($tags_list as $tag) {
	echo $tag.' ';
}
?>

В результате работы этого примера в окне браузера Вы получите следующее:

Второй этап построения облака тегов (вывод облака) заключается в преобразовании показателя релевантности (кол-во вхождений) в размер шрифта результирующей надписи.

В классе я реализовал это следующим образом: в настройках задается минимальный размер шрифта, который соответствует минимальному уровню релевантности (одно вхождение). Все теги с большей релевантностью имеют размер на столько пикселей больше, на сколько больше они имеют вхождений. Шаг изменения можно задавать полем font_size_step, а минимальный размер шрифта полем font_size_min.

Для дальнейшего усовершенствования внешнего вида можно прикрутить облако к небольшому js-скрипту. В результате чего получится такое облако: https://nacmnogo.ru/cloud.html. Подробнее про этот скрипт можно почитать здесь https://habrahabr.ru/blogs/javascript/38264/.

Что ж. У меня все. Удачи!





Читайте также:



23 Ответов на “Облако тегов”

  1. При такой реализации наличие очень популярного тега приведет к тому, что все остальные теги будут отображены одним шрифтом.

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

  3. ууу до решения таких задачек мне еще рано. что-нибудь попроще бы, это да…..

  4. Антон

    Классное облако, эффект 3D поражает. Респектище

  5. cryptus

    Да. Респект чуваку, который написал этот плагин на js :)

  6. cryptus

    2 mr. Hide: Ну это только звучит сложно. На деле - пара строк :)

  7. ну…. как знать) я сча думаю как писать свой дорген)

  8. Решается с помощью кластерного анализа. В двух словах: все теги разбиваются на заданные группы (кластеры) в соответствии их частотности. Теги из одной группы отображаются одним шрифтом.
    Очень популярный тег попадет в отдельную группу, но остальные группы при этом не пострадают.
    Подробнее на английском и реализация:
    [ссылка]

    Я подобный алгоритм сделал на asp.net, если кому надо - обращайтесь.

  9. Спасибо за линк и за новую тему для размышлений :) В посте рассмотрен алгоритм K-средних, где известно заранее кол-во кластеров, которые получатся в результате - самое то, для облака тегов. Но все равно хочется попробывать реализовать какой-нибудь алгоритм с другими исходными данными, поэтому постараюсь к этой теме вернуться еще в этом блоге :)

  10. alex

    честно говоря, никогда не задумывался какими методам это достигается)
    вот они, азы Веб 2.0 :)

  11. foreach ($tags_list as $tag) {
    echo $tag.’ ‘;
    }

    } - лишнее закрытие…

  12. Спасибо, исправил. :)

  13. Спасибо, позновательно. Попробую в своей теме использовать это.

  14. Спасибо огромное, с вашего позволения использую это у себя на сайте.

  15. Дмитрий

    Алгоритм страшный, почему не сделать вот так:

    private function tagscloud($tags) {
    $tags_list = array();

    foreach ($tags as $tag) {
    if(!isset($tags_list[$tag])) {
    $tags_list[$tag] = 1;
    }
    else {
    $tags_list[$tag] += 1;
    }
    }

    return $tags_list;
    }
    Работает быстрее и выглядит понятнее.

  16. cryptus

    2 Дмитрий: Лучше на примере показать почему такая версия не будет работать.
    Допустим есть 3 слова - Картошка (1), Макароны(2) и Телефон(20). В скобках указано кол-во вхождений.
    После преобразования этих чисел в размеры шрифтов с сохранением пропорций мы можем получить 2 слова мелким, почти неразличимым, шрифтом и одно большим шрифтом.

  17. Petrik

    Я как сделать, если при добавлении поста, новости и т.д., в строку через запятую вводить тэги, добавлять в БД, но если совпадения, не предпринимать действий.

  18. Андриус

    А можно пример вбивания тегов в базу, с отрезанием запятулек и грамотным запросом к бд ?

  19. Как-то очень много возни с генерацией тег => кол-во.
    Почему бы не воспользоваться функцией array-count-values ([ссылка]).
    Тогда всё сведётся к
    private function tagscloud($tags) {
    return array-count-values(tags);
    }

    Ну и поиск min/max - оптимально - отсортировать по кол-ву
    через asort и взять первый и последний элементы

  20. […] любого популярного ресурса становится понятие облако тегов или, проще говоря, облако ключевых слов. Любой […]

  21. omgnull

    Будет очень печально, если массив с метками на входе в конструктор окажется большим.

  22. Андрей

    Если записей с популярным тегом будет ооочень много - шрифт будет гигантским - попортит весь дизайн.

    имхо необходимо определить также и максимальный размер шрифта. а остальные по 2 путям можно строить:

    1. самое большое вхождение = самый большой шрифт
    самое маленькое = самый маленький
    остальные = пропорционально весу
    2. самое маленькое вхождение = самый маленький шрифт
    остальные = с шагом
    если значение больше макса, то оно приравнивается максу

  23. 1

    124214


© Copyright. . I-Novice. All Rights Reserved. Terms | Site Map