* @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; } }