Yvision.kz
kk
Разное
Разное
399 773 постов42 подписчика
Всяко-разно
0
00:40, 16 июля 2008

AJAX - Учимся на примерах. Часть 2 - Свое облако тегов.

Blog post image В сегодняшнем уроке мы попытаемся создать такoе модное и актуальное для web 2.0 решение проблемы навигации, как облако тегов (tag cloud, англ). Что это такое - это визуальное представление списка ярлыков (или категорий). Частота упоминаний, поисков, ссылок в интернете с определенного сайта неких слов, терминов, имен, отображается на специальной странице в виде изображения этих слов в формате гиперссылок. Размер изображения тем больше, чем выше релевантность данного слова (термина, имени). Наглядными примерами могут быть облака тегов на самом yvision.kz (пользователи, теги топиков). Целью урока является создание механизма для работы с тегами, и, соответственно вывода их в виде облака. Инструментами послужат PHP и JavaScript фреймворк JQuery, о котором я писал в прошлом уроке.

Как источник используем данные с самого же yvision-а. 1 - Пользователи, 2 - Сообщества. Облако тегов будет строиться в зависимости от рейтинга пользователя/сообщества.

Разделим работу на 3 этапа:

1. Написание парсера для получения данных сайта

2. Создание механизма кэширования результатов

3. Создание механизма для построения облака тегов

Этап номер 1. Источниками данных послужат 2 страницы - список пользователей и список сообществ.

Напишем небольшую функцию, с использованием CURL для получение HTML-кода интересующей нас страницы. В качестве параметра передается URL-адрес.


function
get_html($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
return curl_exec($ch);
curl_close($ch);

}

Для нахождения нужных значений используем уже описанную ранее функцию get_nums():

function get_nums($text, $openingMarker, $closingMarker){
$openingMarkerLength = strlen($openingMarker);
$closingMarkerLength = strlen($closingMarker);
$result = array();
$position = 0;
while (($position = strpos($text, $openingMarker, $position)) !== false) {
$position += $openingMarkerLength;
if (($closingMarkerPosition = strpos($text, $closingMarker, $position)) !== false) {
$result[] = substr($text, $position, $closingMarkerPosition - $position);
$position = $closingMarkerPosition + $closingMarkerLength;
}
}
return $result;

}

Для получения списка пользователей и их рейтинга используем небольшую функцию get_users(), результатом работы которой будет массив со значениями (имя => рейтинг). Поскольку страница пользователей разделена на две части (активные блоггеры, новые блоггеры), мы берем данные только со второй части страницы, чтобы избавиться от лишней работы по удалению дублирующихся результатов.

function get_users(){
$html = get_html('http://yvision.kz/people/');
$data = get_nums($html, 'Новые пользователи</div>', '<div class=bottom>');
$data = substr($data[0], 85, strlen($data[0]) - 118);
$users = get_nums($data, 'bold;"><a class="alogin" href="http://', '.yvision.kz" onfocus');
$rating = get_nums($data, 'jpg"></a><br>', '</div>');
return array_combine($users, $rating);

}

Получение списка сообществ и их рейтинга выглядит похожим образом (функция get_comm()). Примечание: переменная $cmax- это текущее количество страниц с сообществами, на момент написания топика их было 7.

function get_comm(){
$cmax = 7;
for ($i = 1; $i <= $cmax; $i++) {
$html .= get_html('http://yvision.kz/community/' . $i);
}
$names = get_nums($html, 'left;"><a href="http://yvision.kz/community/', '/">');
$data = get_nums($html, '<td class="tmp0">', '</td>');
for($i=2;$i<count($data);){
$rating[] = $data[$i];
$i = $i+3;
}
return array_combine($names, $rating);

}

Этап номер 2. Поскольку данные получаются напрямую с сервера, при этом обновляются не так часто - намного удобнее и практичней кэшировать полученные результаты. Все данные хранятся в виде ассоциативного массива, и самым простым способом кэширования будет сериализация и запись в файл. Для этого напишем две маленькие функции, одна из которых будет записывать данные в кэш, а вторая - их оттуда извлекать.

function set_cache($data, $type){
$data = serialize($data);
$fp = fopen($type.'.txt', 'w');
fputs($fp, $data);
fclose($fp);
}

function
get_cache($type){
$fp = file_get_contents($type.'.txt');
return unserialize($fp);

}

В качестве параметра $data передаем массив с тегами, а в качестве параметра $type - тип данных, который соответствует названию функций получения тегов (для пользователей это - get_users, а для сообществ - get_comm).

Этап номер 3. Работа по постороению облака тегов будет выглядеть следующим образом:

1) Пользователь вводит параметры отображения через форму и отправляет запрос

2) Согласно полученным данным, выводится облако тегов в том виде, в котором запросил сам пользователь.

При этом обмен данными будет проходить в фоновом режиме, т.е. без перезагрузки страницы.

Внешний вид нашего облака будет зависить от следующих параметров: мин. порог рейтинга ($minRate), мин. размер шрифта ($minFontSize), макс. размер шрифта($maxFontSize), способ сортировки ($sortType). Для наглядности, цвет текста будет генерироваться случайно ($fcolor). Размер шрифта для каждой отдельной записи определяется в зависимости от текущего и максимального рейтинга ($fsize) в пределах, определенных самим пользователем с помощью логарифмической функции.

$sortType - это способ сортировки результатов. Их будет 3 - без сортировки (ksort), по возрастанию (asort) и по убыванию (arsort). Сортировка массивов проводится соответственными функциями языка PHP.

function show_cloud($tags, $minRate = 1, $minFontSize = 5, $maxFontSize = 30, $sortType='ksort'){
$fontRange = $maxFontSize - $minFontSize;
$maxTagCnt = 0;
$minTagCnt = 1000000;
foreach ($tags as $n => $r) {
if ($r >= $minRate) {
if ($r > $maxTagCnt) $maxTagCnt = $r;
if ($r < $minTagCnt) $minTagCnt = $r;
}
}
$tagCntRange = $maxTagCnt + 1 - $minTagCount;
$minLog = log($minTagCnt);
$maxLog = log($maxTagCnt);
$logRange = $maxLog - $minLog;
if ($maxLog == $minLog) $logRange = 1;
$sortType($tags);
foreach ($tags as $n => $r) {
$fsize = $minFontSize + $fontRange * (log($r) - $minLog) / $logRange;
$fcolor = dechex(rand(0, 255)) . dechex(rand(0, 255)) . dechex(rand(0, 255));
if ($r >= $minRate) {
printf("<nobr><a style=\"font-size:%dpx;color:#%s\" href=\"#\">%s</a></nobr>\n", (int)$fsize, (string)$fcolor, $n);
}
}

}

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

function get_result(){

var cloud_type = document.getElementById("cloud_type").value;
var sort_type = document.getElementById("sort_type").value;
var minrate = document.getElementById("minrate").value;
var minfont = document.getElementById("minfont").value;
var maxfont = document.getElementById("maxfont").value;
var cache = document.getElementById("cache").value;

$.blockUI({ message: '<b>Обработка данных...</b>' });
$.post(
'index.php',
{
cloud_type: ""+cloud_type+"",
sort_type: ""+sort_type+"",
minrate: ""+minrate+"",
minfont: ""+minfont+"",
maxfont: ""+maxfont+"",
cache: ""+cache+""
},
onAjaxSuccess
);
}

function onAjaxSuccess(data){
$("#result")
.html(data)
.animate({height: "show"}, 900);
$.unblockUI();
}

Определим функцию для обработки события при нажатии кнопки:

$('#submit').bind("click", get_result);

На этом работа завершена. Итогом являются два файла - index.html (форма и отображение) и tags.php (основной скрипт по созданию облака тегов), которые вы можете скачать здесь. И, напоследок, несколько скриншотов работы написанного скрипта:

Blog post image

Blog post image

Blog post image

Blog post image

0