mirror of
https://github.com/cosmocode/dokuwiki-plugin-statdisplay.git
synced 2025-07-23 00:51:10 +00:00
315 lines
9.5 KiB
PHP
315 lines
9.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* statdisplay plugin graph helper component
|
|
*
|
|
* @author Andreas Gohr <gohr@cosmocode.de>
|
|
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
|
|
*/
|
|
class helper_plugin_statdisplay_graph extends DokuWiki_Plugin
|
|
{
|
|
/** @var helper_plugin_statdisplay_log */
|
|
private $log = null;
|
|
|
|
/**
|
|
* Outputs a Graph image
|
|
*
|
|
* @param string $command
|
|
* @param string $from
|
|
* @param string $to
|
|
* @return void
|
|
*/
|
|
public function sendgraph($command, $from = '', $to = '')
|
|
{
|
|
require dirname(__FILE__) . '/../pchart/pData.php';
|
|
require dirname(__FILE__) . '/../pchart/pChart.php';
|
|
require dirname(__FILE__) . '/../pchart/GDCanvas.php';
|
|
require dirname(__FILE__) . '/../pchart/PieChart.php';
|
|
|
|
$this->log = plugin_load('helper', 'statdisplay_log');
|
|
|
|
header('Content-Type: image/png');
|
|
switch ($command) {
|
|
case 'all':
|
|
$this->summary();
|
|
break;
|
|
case 'month by day':
|
|
$this->monthby('day', $from);
|
|
break;
|
|
case 'month by hour':
|
|
$this->monthby('hour', $from);
|
|
break;
|
|
case 'traffic by day':
|
|
$this->trafficby('day', $from);
|
|
break;
|
|
case 'traffic by hour':
|
|
$this->trafficby('hour', $from);
|
|
break;
|
|
case 'traffic by user':
|
|
$this->userdownloads($from);
|
|
break;
|
|
default:
|
|
$this->nograph('No such graph: ' . $command);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show all the access data
|
|
*
|
|
* @param string $from
|
|
* @param string $to
|
|
* @return void
|
|
*/
|
|
private function summary($from = '', $to = '')
|
|
{
|
|
$times = array();
|
|
$hits = array();
|
|
$pages = array();
|
|
$media = array();
|
|
$visitors = array();
|
|
|
|
foreach ($this->log->logdata as $month => $data) {
|
|
if ($month[0] == '_') continue;
|
|
if ($from && $month < $from) continue;
|
|
if ($to && $month > $to) break;
|
|
|
|
$times[] = $month;
|
|
$pages[] = $data['page']['all']['count'] ?? 0;
|
|
$media[] = $data['media']['all']['count'] ?? 0;
|
|
$hits[] = $data['hits']['all']['count'] ?? 0;
|
|
$visitors[] = $data['hits']['all']['visitor'] ?? 0;
|
|
}
|
|
|
|
$title = $this->getLang('t_summary');
|
|
|
|
$this->accessgraph(
|
|
$title,
|
|
$times,
|
|
array(
|
|
$this->getLang('hits'),
|
|
$this->getLang('pages'),
|
|
$this->getLang('media'),
|
|
$this->getLang('visitors'),
|
|
),
|
|
array($hits, $pages, $media, $visitors)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Show month access by day or hour
|
|
*
|
|
* @param string $by either day or hour
|
|
* @param string $date
|
|
*/
|
|
private function monthby($by, $date = '')
|
|
{
|
|
if (!$date) $date = date('Y-m');
|
|
$data = $this->log->logdata[$date];
|
|
|
|
$times = array();
|
|
$hits = array();
|
|
$pages = array();
|
|
$media = array();
|
|
$visitors = array();
|
|
|
|
$keys = array_keys((array)$data['hits'][$by]);
|
|
sort($keys);
|
|
foreach ($keys as $idx) {
|
|
$times[] = $idx;
|
|
$pages[] = $data['page'][$by][$idx]['count'];
|
|
$media[] = $data['media'][$by][$idx]['count'];
|
|
$hits[] = $data['hits'][$by][$idx]['count'];
|
|
$visitors[] = $data['hits'][$by][$idx]['visitor'];
|
|
}
|
|
|
|
$title = sprintf($this->getLang('t_' . $by), $date);
|
|
|
|
$this->accessgraph(
|
|
$title,
|
|
$times,
|
|
array(
|
|
$this->getLang('hits'),
|
|
$this->getLang('pages'),
|
|
$this->getLang('media'),
|
|
$this->getLang('visitors'),
|
|
),
|
|
array($hits, $pages, $media, $visitors)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Show month traffic by day or hour
|
|
*
|
|
* @param string $by either day or hour
|
|
* @param string $date
|
|
*/
|
|
private function trafficby($by, $date = '')
|
|
{
|
|
if (!$date) $date = date('Y-m');
|
|
$data = $this->log->logdata[$date];
|
|
|
|
$times = array();
|
|
$hits = array();
|
|
$pages = array();
|
|
$media = array();
|
|
|
|
foreach (array_keys((array)$data['hits'][$by]) as $idx) {
|
|
$times[] = $idx;
|
|
$pages[] = $data['page'][$by][$idx]['bytes'] / 1024;
|
|
$media[] = $data['media'][$by][$idx]['bytes'] / 1024;
|
|
$hits[] = $data['hits'][$by][$idx]['bytes'] / 1024;
|
|
}
|
|
|
|
$title = 'Traffic';
|
|
|
|
$this->accessgraph(
|
|
$title,
|
|
$times,
|
|
array(
|
|
$this->getLang('all'),
|
|
$this->getLang('pages'),
|
|
$this->getLang('media'),
|
|
),
|
|
array($hits, $pages, $media)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param string $date month to display
|
|
*/
|
|
private function userdownloads($date)
|
|
{
|
|
$usertraffic = $this->log->usertraffic($date);
|
|
if (!$usertraffic) $this->nograph($this->getLang('t_usertraffic') . ': no data');
|
|
|
|
$usertraffic = array_map(function ($in) {
|
|
return $in / 1024 / 1024;
|
|
}, $usertraffic);
|
|
|
|
// get work day average
|
|
if (count($usertraffic)) {
|
|
$avg = $this->log->avg($usertraffic);
|
|
// $avg = $avg / 7 *5; //work day average
|
|
} else {
|
|
$avg = 0;
|
|
}
|
|
arsort($usertraffic); // highest first
|
|
|
|
// limit number of users shown
|
|
$maxusers = 10;
|
|
if (count($usertraffic) > $maxusers + 1) {
|
|
$others = array_slice($usertraffic, $maxusers);
|
|
$usertraffic = array_slice($usertraffic, 0, $maxusers);
|
|
|
|
$other = 0;
|
|
foreach ($others as $user => $traffic) {
|
|
$other += $traffic;
|
|
}
|
|
|
|
$usertraffic[sprintf($this->getLang('others'), count($others))] = $other;
|
|
}
|
|
|
|
// prepare the graph datasets
|
|
$DataSet = new pData();
|
|
$DataSet->addPoints(array_values($usertraffic), "traffic");
|
|
|
|
// setup axis
|
|
$DataSet->AddPoints(array_keys($usertraffic), 'names');
|
|
$DataSet->AddAllSeries();
|
|
$DataSet->SetAbscissaLabelSeries('names');
|
|
$DataSet->removeSeries('names');
|
|
$DataSet->removeSeriesName('names');
|
|
|
|
// create the bar graph
|
|
$Canvas = new GDCanvas(600, 300, false);
|
|
$Chart = new pChart(600, 300, $Canvas);
|
|
|
|
$Chart->setFontProperties(dirname(__FILE__) . '/../pchart/Fonts/DroidSans.ttf', 8);
|
|
$Chart->setGraphArea(50, 40, 600, 200);
|
|
$Chart->drawScale(
|
|
$DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
|
|
45, 1, true
|
|
);
|
|
|
|
$Chart->drawBarGraph($DataSet->GetData(), $DataSet->GetDataDescription());
|
|
//$Chart->drawLegend(500, 40, $DataSet->GetDataDescription(), new Color(250));
|
|
|
|
$Chart->drawTreshold($avg, new Color(128, 0, 0));
|
|
|
|
$Chart->setFontProperties(dirname(__FILE__) . '/../pchart/Fonts/DroidSans.ttf', 12);
|
|
$Chart->drawTitle(10, 10, $this->getLang('t_usertraffic') . ' (MB)', new Color(0), 590, 30);
|
|
|
|
$Chart->Render(null);
|
|
|
|
}
|
|
|
|
/**
|
|
* Draws a line or bargraph depending on the number of data points
|
|
*
|
|
* @param string $title the graph's title
|
|
* @param array $axis the axis points
|
|
* @param array $labels the labels for the datasets
|
|
* @param array $datasets any number of data arrays
|
|
*/
|
|
private function accessgraph($title, $axis, $labels, $datasets)
|
|
{
|
|
if (!count($axis)) {
|
|
$this->nograph($title . ': no data');
|
|
return;
|
|
}
|
|
|
|
// add the data and labels
|
|
$DataSet = new pData();
|
|
foreach ($datasets as $num => $set) {
|
|
$DataSet->AddPoints($set, "series$num");
|
|
$DataSet->SetSeriesName($labels[$num], "series$num");
|
|
}
|
|
|
|
// setup axis
|
|
$DataSet->AddPoints($axis, 'times');
|
|
$DataSet->AddAllSeries();
|
|
$DataSet->SetAbscissaLabelSeries('times');
|
|
$DataSet->removeSeries('times');
|
|
$DataSet->removeSeriesName('times');
|
|
|
|
$Canvas = new GDCanvas(600, 300, false);
|
|
$Chart = new pChart(600, 300, $Canvas);
|
|
$usebargraph = (count($axis) < 10);
|
|
|
|
$Chart->setFontProperties(dirname(__FILE__) . '/../pchart/Fonts/DroidSans.ttf', 8);
|
|
$Chart->setGraphArea(50, 40, 500, 200);
|
|
$Chart->drawScale(
|
|
$DataSet, new ScaleStyle(SCALE_NORMAL, new Color(127)),
|
|
45, 1, $usebargraph
|
|
);
|
|
|
|
if ($usebargraph) {
|
|
$Chart->drawBarGraph($DataSet->GetData(), $DataSet->GetDataDescription());
|
|
} else {
|
|
$Chart->drawLineGraph($DataSet->GetData(), $DataSet->GetDataDescription());
|
|
}
|
|
$Chart->drawLegend(500, 40, $DataSet->GetDataDescription(), new Color(250));
|
|
|
|
$Chart->setFontProperties(dirname(__FILE__) . '/../pchart/Fonts/DroidSans.ttf', 12);
|
|
$Chart->drawTitle(10, 10, $title, new Color(0), 590, 30);
|
|
|
|
$Chart->Render(null);
|
|
}
|
|
|
|
/**
|
|
* Just creates a message
|
|
*
|
|
* @param $title
|
|
*/
|
|
private function nograph($title)
|
|
{
|
|
$Canvas = new GDCanvas(300, 40, false);
|
|
$Chart = new pChart(300, 40, $Canvas);
|
|
$Chart->setFontProperties(dirname(__FILE__) . '/../pchart/Fonts/DroidSans.ttf', 10);
|
|
$Chart->drawTitle(0, 0, $title, new Color(128, 0, 0), 300, 40);
|
|
$Chart->Render(null);
|
|
exit;
|
|
}
|
|
}
|