Je moet je tabel anders / dynamischer laten opbouwen. En je afspraken zo formatteren zodat je makkelijk kan zien wanneer er een afspraak begint en hoelang hij dan duurd in rowspans.
--oude code weg gehaald--
Als je dit doet zou je op de volgende code terug kunnen komen:
Edit code iets opgeschoond en duidelijker gemaakt:
PHP
		
					
			<style type="text/css">
.agenda{
	color:#73879c;	
}
.agenda caption{
	font-size: 20px;
    font-weight: 900;	
}
.agenda td{
	border-bottom: 1px solid #999;
    border-right: 1px solid #999;
    color: #000;
    cursor: pointer;
    padding: 10px 15px;
    transition: all 0.5s ease 0s;	
}
.agenda td.bezet{
	background: #eaeaea;	
}
.agenda th{
	 border-bottom: 1px solid #999;
    border-right: 1px solid #999;
    font-weight: bolder;
    padding: 20px 15px 0 15px;
}
</style>
<?php
$settings["begin_werkdag"] 	= '08:00'; // Begin van werkdag 
$settings["einde_werkdag"] 	= '17:00'; // Eind tijd van werkdag
$settings["tijd_stappen"] 	= '+30 minutes'; //cell span grote 
$settings["start_year"] 	= "2017"; // Jaar van de week die je wil laten zien
$settings["start_week"] 	= "16"; 	// Weeknr die je wil laten zien. 
define('stapgrote',strtotime($settings["tijd_stappen"]) - time()); // Grote van de stappen berekenen
define('start_timestamp',strtotime($settings["start_year"] .'W'.$settings["start_week"].' '.$settings["begin_werkdag"])); // begin datum omzetten naar timestamp
define('einde_timestamp',strtotime($settings["start_year"] .'W'.$settings["start_week"].' '.$settings["einde_werkdag"]));
/* Het volgende is ter illustratie hoe ik aan welke waarde kom. Dit kan je natuurlijk versimpelen */
$afspraken['oud'] = array(
				array('start'=>'2017-04-17 9:00','end'=>'2017-04-17 9:14','titel'=>'test'),
				array('start'=>'2017-04-20 10:30','end'=>'2017-04-20 15:00','titel'=>'Aap')
			);
			
			/* Afspraken omzetten zodat we rowspan weten en de +- begin tijd hebben als array key */ 
	foreach($afspraken['oud'] as $afspraak){
		$round_start = (round(strtotime($afspraak['start']) / stapgrote) * stapgrote);  // Rond start tijd af naar dichtbijzijnde stap.
		$rowspan = round((strtotime($afspraak['end']) - strtotime($afspraak['start'])) / stapgrote); // Bijkijk hoeveel rijen de afsprak inneemt
		$rowspan 									 = $rowspan<=0?1:$rowspan;  	// Rowspan moet minimaal 1 zijn;
		$afspraken['nieuw'][$round_start] 			 = $afspraak; 					//oude info gewoon overnemen
		$afspraken['nieuw'][$round_start]['rowspan'] = $rowspan;					// rowspan toevoegen aan array
		for($i = ($round_start+stapgrote);
			$i <= ($round_start+(stapgrote*($rowspan - 1)));
			$i=($i+stapgrote)){
			$afspraken['bezet'][$i] = true;  // Aangeven welke tijden bezet zijn en dus geen cell hoven te krijgen. 
		}
	}
echo '<table class="agenda">
<caption>Afsprakenoverzicht Week '.$settings["start_week"].'</caption>
<thead><tr><th></th>';
	for($i = start_timestamp; $i <= strtotime('+6 day',start_timestamp); $i = strtotime('+1 day',$i)){
		echo '<th>'.date('d-m',$i).'</th>';	//Datums boven aan tabel zetten//
	}
echo	'</tr></thead>'; 
	for($h = start_timestamp;$h <= einde_timestamp; $h = $h + stapgrote){// Tijden door lopen
		echo '<tr><th>'.date('H:i',$h).'</th>';	
			for($i = $h; $i <= strtotime('+6 day',$h); $i = strtotime('+1 day',$i)){ // Dagen doorlopen. 
				if(isset($afspraken['nieuw'][$i])){//er is een afpsraak die begind op  +- deze tijd. 
				echo '<td class="bezet" data-timestamp="'.$i.'" data-datetime="'.date('Y-m-d H:i',$i).'" rowspan="'.$afspraken['nieuw'][$i]['rowspan'].'">';
					echo $afspraken['nieuw'][$i]['titel'];
				echo '</td>';
				}elseif(empty($afspraken['bezet'][$i])){ // doe niks gezien rowspan
					echo '<td class="vrij" data-timestamp="'.$i.'" data-datetime="'.date('Y-m-d H:i',$i).'"></td>';
				}
			}
		echo '</tr>';
	}
echo'</table>';
?>
