Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rysowanie drzewka tabeli PHP+MySQL
Forum PHP.pl > Forum > PHP
kraks
Witam, bardzo prosze o pomoc. Mam jedna tabele o nazwie schemat_dzialow a w niej 3 pola "id_dzialu", "id_dzialu_nadrzednego" i "nazwa". Wypelnilem rekordy tej tabeli zgodnie ze schematem organizacyjnym, co wyglada mniej wiecej tak:

"id" "id_dzialu_nadrzednego" "nazwa"
1 1 Zarzad
2 1 Dzial1
3 1 Dzial2
19 1 Dzial3
9 1 Dzial4
11 19 Dzial5
12 19 Dzial6
13 19 Dzial7
27 9 Dzial9
28 9 Dzial10
29 9 Dzial11
10 1 Dzial12
7 1 Dzial13
20 7 Dzial14
21 7 Dzial15
22 7 Dzial16

Taki wyglad dzialow przedstawiony w tabeli z nazwa, numerem id i id rodzica nie jest zbyt czytelny dlatego chcialbym narysowac drzewko tej tabeli. Drzewko moze byc narysowane od razu w calosci lub posiadac funkcje zwijania/rozwijania poszczegolnych galezi np znakami + i - na zasadzie np "Dzial13 (+) (-)". Dodam jeszcze ze tabela jest mala, posiada okolo 30 dzialow wiec jakies funkcje zwiekszajace wydajnosc chyba nie sa potrzebne, wystarczy prosta metoda przynajmniej tak mi sie wydaje. Jeszcze raz prosze o pomoc i z gory dziekuje, pozdrawiam.
.radex
Robisz prostą funkcję rekurencyjną.

Tak w uproszczeniu - pseudokod (żebyś zrozumiał działanie)

  1. <?php
  2. function rysuj_drzewo($parent)
  3. {
  4.  $dane = mysql_query( select * from tabela where id_dzialu_nadrzednego == $parent )
  5.  
  6.  $dane = mysql_fetch_object($dane)
  7.  
  8.  tutaj wy&#347;wietlam listę.
  9.  
  10.  rysuj_drzewo($dane->id)
  11.  
  12. }
  13.  
  14. rysuj_drzewo(1)
  15. ?>
miedzna
  1. <?php
  2. function MakeTree(&$Page,&$Name,$Myqsl){
  3.  
  4. $result=mysql_query("SELECT * FROM tabela ORDER BY Name");
  5.  
  6. while($Folder0=list($ID,$Name,$Parent)=@mysql_fetch_array($result)){
  7.  
  8. $table[$Parent][$ID]=$Name;
  9.  
  10. $partable[$ID]=$Parent;
  11.  
  12. $Folder[$ID]=$Folder0;
  13. };
  14.  
  15. $levels=TreeLevels(0,$table,0);
  16.  
  17. $Name=$Folder[$Page]["Name"];
  18.  
  19. if($Page==0){
  20. $results.=TreeExpand(0,$table,$partable,$Folder,$Page,0,1); // 1 na koncu oznacza rozwiniecie do 1 poziomu
  21. }
  22. else{
  23. $ID=$Page;
  24.  
  25. $results.=TreeNodes($ID,$table,$partable,$Folder,$Page,$levels);
  26. }
  27. return $results;
  28. }
  29.  
  30.  
  31. function TreeLevels($Parent,$table,$level){
  32.  
  33. $_SESSION["levels"][$Parent]=$level;
  34.  
  35. while(list($key,$val)=@each($table[$Parent])){
  36.  
  37. if (isset($table[$key])){
  38.  
  39. TreeLevels($key,$table,$level+1);
  40. }
  41. }
  42. return $_SESSION["levels"];
  43. }
  44.  
  45.  
  46. function TreeNodes($ID,$table,$partable,$Folder0,$Page,$levels){
  47.  
  48. $rez0="";
  49.  
  50. if(isset($table[$ID])){
  51.  
  52. $imgwidth="<li style='margin-left:".(($levels[$ID])*10)."px;'>";
  53.  
  54. $lisd=$table[$ID];
  55.  
  56. $ID0=$ID;
  57.  
  58. $fiplevel=$levels[$ID];
  59.  
  60. while(list($key,$val)=each($lisd)){
  61.  
  62. if($Page==$key){
  63.  
  64. $rez0.=$imgwidth."<a href='?Page=".$Folder0[$key]["ID"]."'>".$Folder0[$key]["Name"]."</a></li>";
  65. }
  66. else{
  67. $rez0.=$imgwidth."<a href='?Page=".$Folder0[$key]["ID"]."'>".$Folder0[$key]["Name"]."</a></li>";
  68. }
  69. }
  70. }
  71.  
  72. $res="";
  73.  
  74. while ($ID!=0) {
  75.  
  76. $fip=$partable[$ID];
  77.  
  78. $fiplevel=$levels[$fip];
  79.  
  80. $fiplist=$table[$fip];
  81.  
  82. $imgwidth="<li style='margin-left:".(($fiplevel)*10)."px'>";
  83.  
  84. $rez="";
  85.  
  86. while(list($key,$val)=@each($fiplist)){
  87.  if($Page==$key){
  88.  $rez.=$imgwidth."<a href='?Page=".$Folder0[$key]["ID"]."'><i>".$Folder0[$key]["Name"]."</i></a></li>".$rez0;
  89.  }
  90.  else{
  91.  $rez.=$imgwidth."<a href='?Page=".$Folder0[$key]["ID"]."'>".$Folder0[$key]["Name"]."</a></li>";
  92.  }
  93.  if($ID==$key){
  94.  $rez.=$res; $res="";
  95.  }
  96. }
  97. $res.=$rez;
  98.  
  99. $ID=$partable[$ID];
  100. }
  101. return $rez;
  102. }
  103.  
  104.  
  105.  
  106. function TreeExpand($Parent,$table,$partable,$Folder0,$Page,$level,$levelexpand){
  107.  
  108. $list=$table[$Parent];
  109.  
  110. $width=($level)*10;
  111.  
  112. $result='';
  113.  
  114. while(list($key,$val)=@each($list)){
  115.  
  116. if($level < $levelexpand){
  117.  
  118. $result.="<li style='margin-left:".$width."px;'><a href='?Page=".$Folder0[$key]["ID"]."'>".$Folder0[$key]["Name"]."</a></li>";
  119. }
  120. if (isset($table[$key])){
  121.  
  122. $result.=TreeExpand($key,$table,$partable,$Folder0,$Page,$level+1,$levelexpand);
  123.  
  124. }
  125. }
  126. return $result;
  127. }
  128.  
  129.  
  130. print '<ul>';
  131. print MakeTree($Page,$Name,$Myqsl);
  132. print '</ul>';
  133. ?>


Ten kod powinien Cię zadowolić. Tabela ma strukturę ID, Name, Parent - gdzie ID, to wiadomo, Name to nazwa w Twoim przypadku działu, a Parent, to ID jednostki nadrzędnej (rodzica). Dodaj tylko połączenie z bazą, dopasuj do swoich nazw w tabeli i będzie śmigało, że aż miło. Jak by co, to pisz...
kraks
Witam moja tabela ma strukture id_dzialu, id_dzialu_nadrzednego i nazwa. Dodalem polaczenie z baza, zamienilem wszystkie nazwy na takie jakie wystepuja u mnie (ID na id_dzialu, parent na id_dzialu_nadrzednego, Name na nazwa no i raz w SELECT tabela na schemat_organizacyjny_firmy). Dodam ze moj najwyzszy jedyny rodzic ma id_dzialu=1 i id_dzialu_nadrzednego=1 czyli jes rodzicem sam dla siebie. Dalej dzieci maja np id_dzialu=2 i id_dzialu_nadrzednego=1 itd. Skrypt nie wyrzuca zadnego bledu ale drzewka nie wyswietla (ani niczego innego ). Jeszcze raz prosze o pomoc i z gory dzieki.

  1. <?php
  2. function MakeTree(&$Page,&$nazwa,$Myqsl){
  3.  
  4. $result=mysql_query("SELECT * FROM schemat_organizacyjny_firmy ORDER BY nazwa");
  5.  
  6. while($Folder0=list($id_dzialu,$nazwa,$id_dzialu_nadrzednego)=@mysql_fetch_array($result)){
  7.  
  8. $table[$id_dzialu_nadrzednego][$id_dzialu]=$nazwa;
  9.  
  10. $partable[$id_dzialu]=$id_dzialu_nadrzednego;
  11.  
  12. $Folder[$id_dzialu]=$Folder0;
  13. };
  14.  
  15. $levels=TreeLevels(0,$table,0);
  16.  
  17. $nazwa=$Folder[$Page]["nazwa"];
  18.  
  19. if($Page==0){
  20. $results.=TreeExpand(0,$table,$partable,$Folder,$Page,0,1); 
  21. }
  22. else{
  23. $id_dzialu=$Page;
  24.  
  25. $results.=TreeNodes($id_dzialu,$table,$partable,$Folder,$Page,$levels);
  26. }
  27. return $results;
  28. }
  29.  
  30.  
  31. function TreeLevels($id_dzialu_nadrzednego,$table,$level){
  32.  
  33. $_SESSION["levels"][$id_dzialu_nadrzednego]=$level;
  34.  
  35. while(list($key,$val)=@each($table[$id_dzialu_nadrzednego])){
  36.  
  37. if (isset($table[$key])){
  38.  
  39. TreeLevels($key,$table,$level+1);
  40. }
  41. }
  42. return $_SESSION["levels"];
  43. }
  44.  
  45.  
  46. function TreeNodes($id_dzialu,$table,$partable,$Folder0,$Page,$levels){
  47.  
  48. $rez0="";
  49.  
  50. if(isset($table[$id_dzialu])){
  51.  
  52. $imgwidth="<li style='margin-left:".(($levels[$id_dzialu])*10)."px;'>";
  53.  
  54. $lisd=$table[$id_dzialu];
  55.  
  56. $ID0=$id_dzialu;
  57.  
  58. $fiplevel=$levels[$id_dzialu];
  59.  
  60. while(list($key,$val)=each($lisd)){
  61.  
  62. if($Page==$key){
  63.  
  64. $rez0.=$imgwidth."<a href='?Page=".$Folder0[$key]["id_dzialu"]."'>".$Folder0[$key]["nazwa"]."</a></li>";
  65. }
  66. else{
  67. $rez0.=$imgwidth."<a href='?Page=".$Folder0[$key]["id_dzialu"]."'>".$Folder0[$key]["nazwa"]."</a></li>";
  68. }
  69. }
  70. }
  71.  
  72. $res="";
  73.  
  74. while ($id_dzialu!=0) {
  75.  
  76. $fip=$partable[$id_dzialu];
  77.  
  78. $fiplevel=$levels[$fip];
  79.  
  80. $fiplist=$table[$fip];
  81.  
  82. $imgwidth="<li style='margin-left:".(($fiplevel)*10)."px'>";
  83.  
  84. $rez="";
  85.  
  86. while(list($key,$val)=@each($fiplist)){
  87. if($Page==$key){
  88. $rez.=$imgwidth."<a href='?Page=".$Folder0[$key]["id_dzialu"]."'><i>".$Folder0[$key]["nazwa"]."</i></a></li>".$rez0;
  89. }
  90. else{
  91. $rez.=$imgwidth."<a href='?Page=".$Folder0[$key]["id_dzialu"]."'>".$Folder0[$key]["nazwa"]."</a></li>";
  92. }
  93. if($id_dzialu==$key){
  94. $rez.=$res; $res="";
  95. }
  96. }
  97. $res.=$rez;
  98.  
  99. $id_dzialu=$partable[$id_dzialu];
  100. }
  101. return $rez;
  102. }
  103.  
  104.  
  105.  
  106. function TreeExpand($id_dzialu_nadrzednego,$table,$partable,$Folder0,$Page,$level,$levelexpand){
  107.  
  108. $list=$table[$id_dzialu_nadrzednego];
  109.  
  110. $width=($level)*10;
  111.  
  112. $result='';
  113.  
  114. while(list($key,$val)=@each($list)){
  115.  
  116. if($level < $levelexpand){
  117.  
  118. $result.="<li style='margin-left:".$width."px;'><a href='?Page=".$Folder0[$key]["id_dzialu"]."'>".$Folder0[$key]["nazwa"]."</a></li>";
  119. }
  120. if (isset($table[$key])){
  121.  
  122. $result.=TreeExpand($key,$table,$partable,$Folder0,$Page,$level+1,$levelexpand);
  123.  
  124. }
  125. }
  126. return $result;
  127. }
  128.  
  129.  
  130. print '<ul>';
  131. print MakeTree($Page,$nazwa,$Myqsl);
  132. print '</ul>';
  133. ?>
Nekro
Witam

Proponuje dodac kolumne "level" ktora okresla stopien zagnierzdzenia.

Przyklad zagnierzdzenia
test 1
test 2 1
---- test 3 2
-------test4 3

itd.

Jesli chcesz wyswietlic cale drzewo to pobierasz wszystkie wiersze (sortujac po parentid jak sie nie myle) i lecisz po tablicy wynikowej foreachem.
Podczas wyswietlania ustawiasz "padding-left" elementu na ("level elementu" * 20px) i wtedy dostaniesz wciecia.
Nie jest tu potrzebna zadna rekurencja.
Jesli bedziesz potrzebowall bardziej zaawansowanych operacji na drzewie polecam celkotree (nested set)
miedzna
Witaj, daj dla najwyższego poziomu, czyli dla najważniejszego rodzica ID nie 1, tylko NULL, powinno pomóc.
kraks
miedzna masz na mysli zamiane jedynki na zero w tej linii $results.=TreeExpand(0,$table,$partable,$Folder,$Page,0,1); na $results.=TreeExpand(0,$table,$partable,$Folder,$Page,0,0); czy gdzie powinienem zmienic wartosc tego rodzica na NULL?
miedzna
Nie, w bazie w polu ID dla najwyższego poziomu daj NULL, tylko wtedy skrypt wie, że ta jednostka ma najwyższy poziom.
kraks
Czyli w mojej bazie danych w tabeli, gdzie mam najwyzszego rodzica, ktory aktualnie posiada id_dzialu=1 i id_dzialu_nadrzednego=1 mam zmienic na id_dzialu=0 i id_dzialu_nadrzednego=0 tak?
miedzna
Masz zmienic na id_dzialu=1 i id_dzialu_nadrzednego=NULL exclamation.gif!

smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.