Skip to content

Instantly share code, notes, and snippets.

@koyhoge
Created May 25, 2010 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koyhoge/413252 to your computer and use it in GitHub Desktop.
Save koyhoge/413252 to your computer and use it in GitHub Desktop.
<?php
// $Id$
if (!function_exists('array_val')) {
function array_val(&$data, $key, $default = null) {
if (!is_array($data)) {
return $default;
}
return isset($data[$key])? $data[$key]: $default;
}
}
class TagCloudHelper {
var $options = array(
'wrapTag' => 'div',
'wrapTagClass' => 'tagCloud',
'wrapElement' => '',
'wrapElementClass' => '',
'countLevel' => 6,
'timeLevel' => 6,
'sortTags' => true,
);
var $params = array();
var $elements = array();
public function setOption($option, $val = null) {
if (is_string($option)) {
$this->options[$option] = $val;
} else if (is_array($option)) {
foreach ($option as $name => $val) {
$this->options[$name] = $val;
}
}
}
public function getOption($name) {
return array_val($this->options, $name);
}
public function addElement($name, $link, $count, $timestamp = null) {
if ($timestamp == null) {
$timestamp = time();
}
$this->elements[] = array(
'name' => $name,
'link' => $link,
'count' => $count,
'time' => $timestamp,
);
}
private function cmpElementsName($a, $b) {
if ($a['name'] == $b['name']) {
return 0;
}
return ($a['name'] < $b['name'])? -1: 1;
}
public function sortElements() {
usort($this->elements, array($this, 'cmpElementsName'));
}
public function calcFactor($level, $max, $min) {
if ($max == $min) {
return 1;
} else {
return $level / (sqrt($max) - sqrt($min));
}
}
public function calcParams() {
$total = count($this->elements);
if ($total == 0) {
return;
} else if ($total == 1) {
$elem = $this->elements[0];
$this->params = array(
'minCount' => $elem['count'],
'maxCount' => $elem['count'],
'minTime' => $elem['time'],
'maxTime' => $elem['time'],
'countFactor' => 1,
'timeFactor' => 1,
);
return;
}
$counts = array();
$times = array();
foreach ($this->elements as $elem) {
if (isset($elem['count'])) {
$counts[] = (int)$elem['count'];
} else {
$counts[] = 0;
}
if (isset($elem['time'])) {
$times[] = (int)$elem['time'];
} else {
$times[] = 0;
}
}
$this->params = array(
'minCount' => min($counts),
'maxCount' => max($counts),
'minTime' => min($times),
'maxTime' => max($times),
);
$countFactor = $this->calcFactor(
$this->getOPtion('countLevel'),
$this->params['maxCount'],
$this->params['minCount']);
$timeFactor = $this->calcFactor(
$this->getOption('timeLevel'),
$this->params['maxTime'],
$this->params['minTime']);
$this->params['countFactor'] = $countFactor;
$this->params['timeFactor'] = $timeFactor;
}
public function getCountLevel($count) {
$min = $this->params['minCount'];
$max = $this->params['maxCount'];
$fac = $this->params['countFactor'];
if ($min == $max) {
return (int)($this->getOption('countLevel') / 2);
}
return (int)((sqrt($count) - sqrt($min)) * $fac);
}
public function wrapAnything($contents, $tag, $class) {
if (empty($tag)) {
return $contents;
}
$attClass = '';
if (!empty($class)) {
$attClass = ' class="' . $class . '"';
}
$result =
'<' . $tag . $attClass . '>' .
$contents .
'</' . $tag . '>';
return $result;
}
public function renderElement($element) {
$contents = htmlspecialchars($element['name']);
$link = $element['link'];
if (!empty($link)) {
$contents = '<a href="' . $link . '">' . $contents . '</a>';
}
$lvclass = $this->getOption('countLevelClasses');
if (!empty($lvclass)) {
$countLevel = $this->getCountLevel($element['count']);
if ($countLevel > (count($lvclass) - 1)) {
$countLevel = count($lvclass) - 1;
}
$wrapElementClass = $lvclass[$countLevel];
} else {
$wrapElementClass = $this->getOption('wrapElementClass');
}
$wrapElement = $this->getOption('wrapElement');
return $this->wrapAnything($contents, $wrapElement, $wrapElement
Class);
}
public function wrapTags($contents) {
$wrapTag = $this->getOption('wrapTag');
$wrapTagClass = $this->getOption('wrapTagClass');
return $this->wrapAnything($contents, $wrapTag, $wrapTagClass);
}
public function render() {
$this->calcParams();
if ($this->getOption('sortTags')) {
$this->sortElements();
}
$result = '';
foreach ($this->elements as $element) {
$result .= $this->renderElement($element);
}
return $this->wrapTags($result);
}
}
$cats = array(
'Cupcake' => 17,
'Donuts' => 23,
'Eclair' => 38,
'Froyo' => 17,
'Gingerbread' => 1,
);
$levels = array(
'level1',
'level2',
'level3',
'level4',
'level5',
'level6',
'level7',
'level8',
);
$tags = new TagCloudHelper();
$tags->setOption(
array(
'wrapTag' => '',
'wrapElement' => 'li',
'countLevel' => 8,
'countLevelClasses' => $levels,
));
foreach ($cats as $name => $count) {
$link = 'http://hoge.org/android/' . $name;
$tags->addElement($name, $link, $count);
}
$res = $tags->render();
var_dump($res);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment