2011-09-26 8 views
9

Ecco un rompicapo per i più coraggiosi. Ci sono stato per giorni e non posso venire con la soluzione.Come rappresentare un albero binario con tabelle (html)?

volevo venire fuori con qualcosa di simile:

enter image description here

utilizzando HTML, CSS e PHP solo.

Mi sono avvicinato, ma non proprio quello che mi aspettavo. Here is the code in PHP e here is the output.

<table border="0"> 
<thead> 
    <tr> 
     <th>Cientoveintiochavos</th> 
     <th>Seseintaicuatravos</th> 
     <th>Treintaidosavos</th> 
     <th>Dieciseisavos</th> 
     <th>Octavos</th> 
     <th>Cuartos</th> 
     <th>Semifinales</th> 
     <th>Final</th> 
    </tr> 
</thead> 
<tbody> 
<?php for($i=0;$i<256;$i++): ?> 
    <tr> 
     <?php for($n=0,$c=2;$n<8;$n++,$c*=2): ?> 
      <?php 
      /* 
      if(false){//$i == 0) { 
       $rwspn = $c/2+1; 
       $iter = 0; 
      } else { 
       $rwspn = $c; 
       $iter = $c;//-$c/2+1; 
      } 
      */ 
      $class = ($i%($c*2))?'par':'impar winner'; 
      if($i%$c==0):?> 
       <td rowspan="<?=$c;?>" class="<?=$class;?>"><span><?php echo genRandomString();?></span></td> 
      <?php endif; ?> 
     <?php endfor; ?> 
    </tr> 
<?php endfor; ?> 
</tbody> 
</table> 

Se qualcuno sa come rappresentare un albero binario o un dendrogramma o esce con un codice intelligente per favore fatemelo sapere!

risposta

3

Ho fatto qualcosa di simile, usando un tipo di div come @HugoDelsing. Il modo in cui ho trattato le linee era quella di dividere ciascuna coppia in 4 div verticalmente sovrapposti:

  1. il primo giocatore (border-bottom)
  2. Un distanziatore tra 1 ° e 2 giocatori (bordo destro)
  3. il secondo giocatore (border-bottom e border-right)
  4. Un distanziatore prima che la coppia successiva (senza bordi)

Ognuno di questi ottiene 1/4 l'altezza della coppia *, e l'altezza totale del una coppia viene raddoppiata mentre ci si sposta a destra. Se non si dispone di una potenza di due, riempire gli slot con segnaposto per spingere tutto in basso la giusta quantità.

* I bordi inferiori eliminano le altezze di 1, quindi tenetene conto quando si impostano le righe.

Altre note
div distanziatori possono non essere necessari, ma per me hanno trattato facilmente la distanza e ottenere le diverse colonne per allineare correttamente.

ho stili inline compilati da PHP per le altezze usato, quindi non ho avuto un limite di profondità arbitraria o calcoli hard-coded in CSS.

Here's an example.

EDIT
OK, qui è teh codez:

<style type="text/css"> 
    .round{ 
     float:left; 
     width:200px; 
    } 
    .firstTeam, .secondTeam{ 
     border-bottom:1px solid #ccc; 
     position:relative; 
    } 
    .firstSpacer, .secondTeam{ 
     border-right:1px solid #ccc; 
    } 
    .team{ 
     position:absolute; 
     bottom: 4px; 
     left: 8px; 
    } 
</style> 
<div class="round"> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:29px;"><div class="team">Team One</div></div> 
     <div class="firstSpacer" style="height:30px;">&nbsp;</div> 
     <div class="secondTeam" style="height:29px;"><div class="team">Team Two</div></div> 
     <div class="secondSpacer" style="height:30px;">&nbsp;</div> 
    </div> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:29px;"><div class="team">Team Three</div></div> 
     <div class="firstSpacer" style="height:30px;">&nbsp;</div> 
     <div class="secondTeam" style="height:29px;"><div class="team">Team Four</div></div> 
     <div class="secondSpacer" style="height:30px;">&nbsp;</div> 
    </div> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:29px;"><div class="team">Team Five</div></div> 
     <div class="firstSpacer" style="height:30px;">&nbsp;</div> 
     <div class="secondTeam" style="height:29px;"><div class="team">Team Six</div></div> 
     <div class="secondSpacer" style="height:30px;">&nbsp;</div> 
    </div> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:29px;"><div class="team">Team Seven</div></div> 
     <div class="firstSpacer" style="height:30px;">&nbsp;</div> 
     <div class="secondTeam" style="height:29px;"><div class="team">Team Eight</div></div> 
     <div class="secondSpacer" style="height:30px;">&nbsp;</div> 
    </div> 
</div> 
<div class="round"> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:59px;"><div class="team">Team One</div></div> 
     <div class="firstSpacer" style="height:60px;">&nbsp;</div> 
     <div class="secondTeam" style="height:59px;"><div class="team">Team Three</div></div> 
     <div class="secondSpacer" style="height:60px;">&nbsp;</div> 
    </div> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:59px;"><div class="team">Team Five</div></div> 
     <div class="firstSpacer" style="height:60px;">&nbsp;</div> 
     <div class="secondTeam" style="height:59px;"><div class="team">Team Eight</div></div> 
     <div class="secondSpacer" style="height:60px;">&nbsp;</div> 
    </div> 
</div> 
<div class="round"> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:119px;">&nbsp;</div> 
     <div class="firstSpacer" style="height:120px;">&nbsp;</div> 
     <div class="secondTeam" style="height:119px;">&nbsp;</div> 
     <div class="secondSpacer" style="height:120px;">&nbsp;</div> 
    </div> 
</div> 
<div class="round"> 
    <div class="matchup"> 
     <div class="firstTeam" style="height:239px;">&nbsp;</div> 
    </div> 
</div> 
+0

si potrebbe incollare un esempio di codice o un jsfiddle per una più facile visualizzazione? sembra proprio quello che stavo cercando, grazie –

+0

@NaoiseGolden: aggiunto codice di esempio. – grossvogel

0

Non userei un tavolo ma div.

  • creare un div contenitore colonna con posizione relativa/assoluta con larghezza fissa (ad esempio: 200px) per ogni colonna.
  • Ogni contenitore colonna ha div interni con altezza e lineHeight del doppio della precedente contenitore colonna
  • creare un'immagine linea nera verticale lungo (lunghezza atleast la metà delle dimensioni del più grande altezza del div interni in qualsiasi colonna. Avviare il linea con una linea orizzontale di 200 px a sinistra (ruotare una L di 180 gradi). Lascia circa la metà dell'altezza del testo dello spazio libero sopra la linea orizzontale nell'immagine, quindi la linea sarà sotto il testo
  • set questa immagine come sfondo per il div interno di ogni contenitore di colonne e posizionarlo al centro a sinistra, ripetere = nessuno;

Alcuni codice di esempio (senza immagini)

<style type="text/css"> 
div.col { position:absolute;border:1px solid #f00;width:200px;top:0px; } 
div.col1 { left:0px; } 
div.col1 div { height:20px; line-height:20px; } 
div.col2 { left:200px; } 
div.col2 div { height:40px; line-height:40px; } 
div.col3 { left:400px; } 
div.col3 div { height:80px; line-height:80px; } 
div.col4 { left:600px; } 
div.col4 div { height:160px; line-height:160px; } 
div.col5 { left:800px; } 
div.col5 div { height:320px; line-height:320px; } 
</style> 


<div class='col1 col'> 
    <div>player1</div> 
    <div>player2</div> 
    <div>player3</div> 
    <div>player4</div> 
    <div>player5</div> 
    <div>player6</div> 
    <div>player7</div> 
    <div>player8</div> 
    <div>player9</div> 
    <div>player10</div> 
    <div>player11</div> 
    <div>player12</div> 
    <div>player13</div> 
    <div>player14</div> 
    <div>player15</div> 
    <div>player16</div> 
</div> 
<div class='col2 col'> 
    <div>player1</div> 
    <div>player3</div> 
    <div>player5</div> 
    <div>player7</div> 
    <div>player9</div> 
    <div>player11</div> 
    <div>player13</div> 
    <div>player15</div> 
</div> 
<div class='col3 col'> 
    <div>player1</div> 
    <div>player5</div> 
    <div>player9</div> 
    <div>player13</div> 
</div> 
<div class='col4 col'> 
    <div>player1</div> 
    <div>player9</div> 
</div> 
<div class='col5 col'> 
    <div>player1</div> 
</div> 
+0

approccio interessante. Ho fatto un violino [qui] (http://jsfiddle.net/naoise/ez5N2/), ma ancora non riesce a vedere come gestire le linee come nell'immagine. –

0

Sembra che tu sia quasi arrivato. Bel lavoro! Penso che l'allineamento centrale desiderato sia nei CSS

td { 
    vertical-align: middle; 
} 

Non penso che si possano far funzionare le linee usando i bordi. Potresti provare invece un'immagine di sfondo per loro.

+0

che è di destra, le linee non funzionano in modo che non è la soluzione (♫ niau niau niau, più fortuna la prossima volta! ♫) In realtà c'è di più ad esso che soddisfa l'occhio. Ho alcuni documenti con le rappresentazioni e le formule, che fanno una buona approssimazione, ma manca qualcosa e non posso continuare con esso al momento. Forse ha un'approssimazione più semplice. –