224 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| require_once 'ExtendedGitGraph.php';
 | |
| require_once 'SingleCommitInfo.php';
 | |
| require_once 'Utils.php';
 | |
| 
 | |
| class EGHRenderer
 | |
| {
 | |
| 	const DIST_X     = 13;
 | |
| 	const DIST_Y     = 13;
 | |
| 	const DAY_WIDTH  = 11;
 | |
| 	const DAY_HEIGHT = 11;
 | |
| 
 | |
| 	const COMMITCOUNT_COLOR_UPPERLIMIT = 16;
 | |
| 
 | |
| 	const COLOR_SCHEMES =
 | |
| 		[
 | |
| 			'custom'    => ['#F5F5F5', '#DBDEE0', '#C2C7CB', '#AAB0B7', '#9099A2', '#77828E', '#5E6B79', '#455464', '#2C3E50'],
 | |
| 			'standard'  => ["#ebedf0", "#c6e48b", "#7bc96f", "#239a3b", "#196127"],
 | |
| 			'modern'    => ["#afaca8", "#d6e685", "#8cc665", "#44a340", "#1e6823"],
 | |
| 			'gray'      => ["#eeeeee", "#bdbdbd", "#9e9e9e", "#616161", "#212121"],
 | |
| 			'red'       => ["#eeeeee", "#ff7171", "#ff0000", "#b70000", "#830000"],
 | |
| 			'blue'      => ["#eeeeee", "#6bcdff", "#00a1f3", "#0079b7", "#003958"],
 | |
| 			'purple'    => ["#eeeeee", "#d2ace6", "#aa66cc", "#660099", "#4f2266"],
 | |
| 			'orange'    => ["#eeeeee", "#ffcc80", "#ffa726", "#fb8c00", "#e65100"],
 | |
| 			'halloween' => ["#eeeeee", "#ffee4a", "#ffc501", "#fe9600", "#03001c"],
 | |
| 		];
 | |
| 
 | |
| 	const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
 | |
| 	const DAYS   = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
 | |
| 
 | |
| 	/* @var ExtendedGitGraph */
 | |
| 	private $owner;
 | |
| 	/* @var SingleCommitInfo[] */
 | |
| 	public $data;
 | |
| 	/* @var string */
 | |
| 	public $colorScheme = 'standard';
 | |
| 	/* @var int[] */
 | |
| 	public $yearList;
 | |
| 	/* @var array */
 | |
| 	public $commitMap; // date('Y-m-d') -> count
 | |
| 
 | |
| 	public function __construct($egh) {
 | |
| 		$this->owner = $egh;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $data SingleCommitInfo[]
 | |
| 	 */
 | |
| 	public function init($data)
 | |
| 	{
 | |
| 		$this->data = $data;
 | |
| 
 | |
| 		$this->yearList = $this->getYears($data);
 | |
| 		$this->owner->out("Found " . count($this->yearList) . " year to generate.");
 | |
| 
 | |
| 		$this->commitMap = $this->generateCommitMap($data, $this->yearList);
 | |
| 		$this->owner->out("Commitmap with ".count($this->commitMap)." entries generated.");
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $data SingleCommitInfo[]
 | |
| 	 * @return int[]
 | |
| 	 */
 | |
| 	public function getYears($data) {
 | |
| 		$years = array();
 | |
| 
 | |
| 		foreach	($data as $commit) {
 | |
| 			if(! in_array($commit->Timestamp->format('Y'), $years))
 | |
| 				$years[] = intval($commit->Timestamp->format('Y'));
 | |
| 		}
 | |
| 
 | |
| 		asort($years);
 | |
| 
 | |
| 		return $years;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $data SingleCommitInfo[]
 | |
| 	 * @param $yearList int[]
 | |
| 	 * @return array
 | |
| 	 */
 | |
| 	private function generateCommitMap($data, $yearList)
 | |
| 	{
 | |
| 		$result = [];
 | |
| 
 | |
| 		foreach ($yearList as $year)
 | |
| 		{
 | |
| 			$ymap = [];
 | |
| 
 | |
| 			$date = new DateTime($year . '-01-01');
 | |
| 			while($date->format('Y') == $year)
 | |
| 			{
 | |
| 				$ymap[$date->format('Y-m-d')] = 0;
 | |
| 				$date = $date->modify("+1 day");
 | |
| 			}
 | |
| 
 | |
| 			foreach	($data as $commit)
 | |
| 			{
 | |
| 				if(array_key_exists($commit->Timestamp->format('Y-m-d'), $ymap)) $ymap[$commit->Timestamp->format('Y-m-d')]++;
 | |
| 			}
 | |
| 
 | |
| 			$result = array_merge($result, $ymap);
 | |
| 		}
 | |
| 
 | |
| 
 | |
| 		return $result;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $year int
 | |
| 	 * @return int
 | |
| 	 */
 | |
| 	private function getMaxCommitCount($year)
 | |
| 	{
 | |
| 		$max = 0;
 | |
| 		foreach ($this->commitMap as $date => $count) if (Utils::startsWith($date, strval($year))) $max = max($max, $count);
 | |
| 		return $max;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param $year int
 | |
| 	 * @return string
 | |
| 	 */
 | |
| 	public function render($year)
 | |
| 	{
 | |
| 		$now = new DateTime();
 | |
| 		$date = new DateTime($year . '-01-01');
 | |
| 		$monthlist = array_fill(0, 12, [0, 0]);
 | |
| 		$colors = self::COLOR_SCHEMES[$this->colorScheme];
 | |
| 
 | |
| 		$ymapmax = $this->getMaxCommitCount($year);
 | |
| 		$exponent = log(0.98/(count($colors)-1), 1/$ymapmax); // (1/max)^n = 0.98   // => 1 commit erreicht immer genau die erste stufe
 | |
| 
 | |
| 		$html = '';
 | |
| 
 | |
| 		$html .= '<div class="extGitGraphContainer">' . "\n";
 | |
| 		$html .= '<svg class="git_list" viewBox="0 0 715 115">' . "\n";
 | |
| 		$html .= '<g transform="translate(20, 20) ">' . "\n";
 | |
| 		$html .= '<g transform="translate(0, 0)">' . "\n";
 | |
| 
 | |
| 		$week = 0;
 | |
| 		$wday = 0;
 | |
| 		while($date->format('Y') == $year)
 | |
| 		{
 | |
| 			if ($date > $now) // THE FUTURE, SPONGEBOB
 | |
| 			{
 | |
| 				while ($date->format('d') != $date->format('t'))
 | |
| 				{
 | |
| 					if ($date->format('N') == 1 && $date->format('z') > 0) $week++;
 | |
| 					$date = $date->modify("+1 day");
 | |
| 				}
 | |
| 				$monthlist[$date->format('m') - 1][1] = $week + ($wday / 7);
 | |
| 
 | |
| 				$date = $date->modify("+1 year"); // Kill
 | |
| 				continue;
 | |
| 			}
 | |
| 
 | |
| 			$c_count = $this->commitMap[$date->format('Y-m-d')];
 | |
| 			$color_idx = min((count($colors)-1), ceil(pow($c_count/$ymapmax, $exponent) * (count($colors)-1)));
 | |
| 			$color = $colors[$color_idx];
 | |
| 
 | |
| 			$wday = ($date->format('N') - 1);
 | |
| 
 | |
| 			if ($date->format('N') == 1 && $date->format('z') > 0)
 | |
| 			{
 | |
| 				$html .= '</g>' . "\n";
 | |
| 				$week++;
 | |
| 				$html .= '<g transform="translate(' . $week * self::DIST_X . ', 0)">' . "\n";
 | |
| 			}
 | |
| 
 | |
| 			if ($date->format('d') == 1)
 | |
| 			{
 | |
| 				$monthlist[$date->format('m') - 1][0] = $week + ($wday / 7);
 | |
| 			}
 | |
| 			else if ($date->format('d') == $date->format('t'))
 | |
| 			{
 | |
| 				$monthlist[$date->format('m') - 1][1] = $week + ($wday / 7);
 | |
| 			}
 | |
| 
 | |
| 			$html .=  '<rect'.
 | |
| 				' style='            .'"fill:'.$color.';'     . '"' .
 | |
| 				' y="'               . ($wday * self::DIST_Y) . '"' .
 | |
| 				' height="'          . self::DAY_HEIGHT       . '"' .
 | |
| 				' width="'           . self::DAY_WIDTH        . '"' .
 | |
| 				' class="'           . 'egg_rect'             . '"' .
 | |
| 				' data-count="'      . $c_count               . '"' .
 | |
| 				' data-date="' . ' ' . $date->format('Y-m-d') . '"' .
 | |
| 				'></rect>' . "\n";
 | |
| 
 | |
| 			$date = $date->modify("+1 day");
 | |
| 		}
 | |
| 
 | |
| 		$html .= '</g>' . "\n";
 | |
| 
 | |
| 		for($i = 0; $i < 12; $i++)
 | |
| 		{
 | |
| 			if ($monthlist[$i][1]-$monthlist[$i][0] > 0)
 | |
| 			{
 | |
| 				$posx = (($monthlist[$i][0]+$monthlist[$i][1])/2) * self::DIST_X;
 | |
| 				$html .=  '<text y="-3" x="' . $posx . '" style="text-anchor: middle" class="caption_month">' . self::MONTHS[$i] . '</text>' . "\n";
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		for($i = 0; $i < 7; $i++) {
 | |
| 			$html .=  '<text y="' . ($i*self::DIST_Y + self::DAY_HEIGHT/2) . '" x="-6" style="text-anchor: middle" class="caption_day" dominant-baseline="central">' . self::DAYS[$i] . '</text>' . "\n";
 | |
| 		}
 | |
| 
 | |
| 		$html .=  '<text  x="-10" y="-5" class="caption">' . $year . '</text>' . "\n";
 | |
| 
 | |
| 		$html .= '</g>' . "\n";
 | |
| 		$html .= '</svg>' . "\n";
 | |
| 		$html .= '<div class="svg-tip n">' . "\n";
 | |
| 		$html .= '<strong> </strong><span> </span>' . "\n";
 | |
| 		$html .= '</div>' . "\n";
 | |
| 		$html .= '<div class="egg_footer">' . "\n";
 | |
| 		$html .= '<a href="https://www.mikescher.com/programs/view/ExtendedGitGraph">extendedGitGraph</a>' . "\n";
 | |
| 		$html .= '</div>' . "\n";
 | |
| 		$html .= '</div>' . "\n";
 | |
| 
 | |
| 
 | |
| 		return $html;
 | |
| 	}
 | |
| } |