Staggan Posted December 15, 2011 Share Posted December 15, 2011 Hello I have an array that I would like to display as a family tree... and am looking for an example script that will allow me to do this. I want to be able to create X number of generations and fill the boxes with data from my array.... So, if I want 5 generations I want to generate a tree with 63 elements or boxes Any help would be appreciated Thanks Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/ Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 What is the format of the array and how do you want the output to look? Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298200 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 Here is a small script that will create a table in the general format of a family tree based upon the number of generations given. But, I would need to know the format of your input array to know how to populate the contents. <?php $generations = 5; $total_columns = pow(2, $generations); $familyTree = ''; for($gen = 0; $gen <= $generations; $gen++) { $gen_family_count = pow(2, $gen); $colspan = $total_columns / $gen_family_count; $familyTree .= "<tr>\n"; for($i=0; $i<$gen_family_count; $i++) { $familyTree .= "<td colspan='{$colspan}'>{$i}</td>\n"; } $familyTree .= "<tr>\n"; } ?> <html> <head> <style> td { text-align: center; } </style> </head> <body> <table border='1'> <?php echo $familyTree; ?> </table> </body> </html> Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298204 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Hello My array is formatted as follows: 0 first level 2, 1 second level 6, 5, 4, 3 third level and so on, populating from right to left Here is a complete example of the array: Array ( [0] => Kegluneq Aaliyah [1] => Arctictreks Dark As Night [2] => Arctictrek Silver Spirit [3] => KEBUCK SCHRIMSHANDER [4] => ARCTICTREKS CHERISH FOREVER [7] => Pat Gagnon [8] => Coquette La Rouge D'Ericlam [15] => Ewok D'Ericlam [16] => Heidi D'Ericlam [31] => David Le Noir D'Ericlam [32] => B-Wouack De Patcie [33] => Comanche D'Ericlam [34] => Finskan D'Ericlam [17] => Himmuk D'Ericlam [18] => Inouska D'Ericlam [35] => Comanche D'Ericlam [36] => Finskan D'Ericlam [37] => Diable Le Rouge D'Ericlam [38] => Frosty D'Ericlam [9] => Storm Kloud's Chosen to Win [10] => Arctictrek's Indiana [19] => Storm Kloud's Keep the Win [20] => Storm Kloud's Hharmony [39] => Storm Kloud's Oomiak [40] => Storm Kloud Ddawn In The North [41] => Storm Kloud's Better Than Ever [42] => Princess Nikkita Sno-Kloud [21] => Jacbar Alaskan Black Night [22] => Rameslyn Cherokee Squaw [43] => Highnoons Kaskinampo of Jacbar [44] => Malnorska's Gypsy Lady [45] => Fire 'N Ice In Conclusion [46] => Highnoons Loucheuse [5] => Shepherdsway Touch of Gold [6] => Arctictreks Legend of a Lady [11] => Outriggers Red Wolf [12] => Eastern Hill Coldfoot Coco [23] => Keikewabic's P'Tis Guy [24] => Keikewabic's Chitina [47] => Keikewabic's P'Tis N'Ours [48] => Keikewabic's Mitchie [49] => Keikewabic's P'Tis N'Ours [50] => Keikewabic & Burley's Merlin [25] => Yukon (N5) [26] => Ivalos Ayla [51] => A-Mikko [52] => B Ika Tanana [53] => Ivalos Froststar [54] => Chinooks Ivalo [13] => Shepherdsway Phantom Scout [14] => Arctictrek's Indiana [27] => Storm Kloud's Chosen to Win [28] => Shepherdsway Black Oasis [55] => Storm Kloud's Keep the Win [56] => Storm Kloud's Hharmony [57] => Fire 'N Ice In Conclusion [58] => Highnoons Ottawa [29] => Jacbar Alaskan Black Night [30] => Rameslyn Cherokee Squaw [59] => Highnoons Kaskinampo of Jacbar [60] => Malnorska's Gypsy Lady [61] => Fire 'N Ice In Conclusion [62] => Highnoons Loucheuse ) I already know the number of generations because I set that at the beginning Thanks Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298217 Share on other sites More sharing options...
xyph Posted December 15, 2011 Share Posted December 15, 2011 Is there any reason why the keys are out of order? Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298219 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 It seems to be the way my recursive function returns the indexes.... I can reorder it if need be.... Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298223 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 OK, so, I have it working.... thank you... but some more advice if you could... here is the changed code: $generations = $numLevelsToSearch; $elements = 0 ; $total_columns = pow(2, $generations); $familyTree = ''; for($gen = 0; $gen <= $generations; $gen++){ $gen_family_count = pow(2, $gen); $colspan = $total_columns / $gen_family_count; $familyTree .= "<tr>\n"; for($i=0; $i<$gen_family_count; $i++){ $elements +=1; $familyTree .= "<td colspan='{$colspan}'>{$familyTreeArray[$elements]}</td>\n"; } $familyTree .= "<tr>\n";} echo $elements; ?> <html><head> <style> td { text-align: center; } </style></head><body><table border='1'> <?php echo $familyTree; ?></table></body></html> <? How can I increase the spacing and is it possible to also do this horizontally? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298226 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Actually, it is not quite right.... not sure what is wrong though.... think the positions are off a little. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298228 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Fixed that... I was adding to $elements in the loop before displaying it.. moved it to after and it works now... Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298229 Share on other sites More sharing options...
xyph Posted December 15, 2011 Share Posted December 15, 2011 It really depends. foreach will loop through the arrays in whatever order they're already in for will loop through the keys in numerical order. <?php $family = range(0,62); $familySize = count( $family ); // This will determine how many columns will be in our biggest branch // http://en.wikipedia.org/wiki/Power_of_two#Algorithm_to_convert_any_number_into_nearest_power_of_two_number $colspan = pow(2,ceil(log($familySize/2,2))); $x = 1; $y = 1; echo '<table border="1">'; foreach( $family as $member ) { if( $x == 1 ) echo '<tr>'; echo '<td colspan="'.$colspan.'">'.$member.'</td>'; if( $x == pow(2,$y-1) ) { echo '</tr>'; $colspan /= 2; $y++; $x = 1; } else $x++; } echo '</table>'; ?> Keep in mind, the code won't create blank cells if the data doesn't 'fit' perfectly into the tree. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298238 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Hi... It all works, thanks. I don't have empty elements I fill them with "No Details" so it still gives the complete pedigree. I would still like to know if I can display this from left to right as an option though, is that possible? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298239 Share on other sites More sharing options...
xyph Posted December 15, 2011 Share Posted December 15, 2011 Of course it is. You'd have to show us how you want it displayed though. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298241 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Thanks... 3 1 4 0 5 2 6 I hope that makes sense ? Thanks again Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298244 Share on other sites More sharing options...
xyph Posted December 15, 2011 Share Posted December 15, 2011 Of course, you're going to have to do different calculations though. Here's a helpful graph 0 1 3 7 15 31 32 16 33 34 8 17 35 36 18 37 38 4 9 19 39 40 20 41 42 10 21 43 44 22 45 46 2 5 11 23 47 48 24 49 50 12 25 51 52 26 53 54 6 13 27 55 56 28 57 58 14 29 59 60 30 61 62 You need to turn that into a table, using rowspan. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298248 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Thanks... trying to figure it out Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298256 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 Yeah, that is going to be much more complicated as you will need to build the rows in a more complex format. Not impossible, but will take some analytical and mathematical skills. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298257 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Not getting very far, heh. I understand my first rowspan should be = to the number of rows I'll need. Which for a 3 generation pedigree is 8 rows... so my first row span should be 8 rows with a single value my second should be 2 entries, each spanning 4 rows my third should be 4 entries each spanning 2 rows and my last 8 entries each spannnig a single row... But I am not sure how to build this table, let alone populate it yet.... I am sure I am being stupid but not sure why... everything I have tried so far just gives me some wierd layout.... Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298284 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 Ok, here you go. I'm not even going to try and explain the logic <?php $generations = 3; //Create temp array to store results $genTableArray = array(); for($genCol = 0; $genCol <= $generations; $genCol++) { $genRowCount = pow(2, $genCol); $rowspan = pow(2, $generations) / $genRowCount; for($familyGenCount=0; $familyGenCount<$genRowCount; $familyGenCount++) { $personIndex = pow(2, $genCol) + $familyGenCount - 1; $rowIndex = $rowspan * $familyGenCount; $genTableArray[$rowIndex][] = "<td rowspan='{$rowspan}'>$personIndex - {$familyTreeArray[$personIndex]}</td>\n"; } } //Output the array into a table ksort($genTableArray); $familyTreeHTML = ''; foreach($genTableArray as $rowData) { $familyTreeHTML .= "<tr>\n" . implode("\n", $rowData) . "</tr>\n"; } ?> <html> <head> <style> td { text-align: center; } </style> </head> <body> <table border='1'> <?php echo $familyTreeHTML; ?> </table> </body> </html> I tried to write it to create the table directly, but couldn't figure out the formulas to determine which records to output on each row. So, I just processed the records similar to the original scripts but then dynamically populate an array. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298289 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Thank you for your help.... I'll spend some time going over this to understand it.... Thanks again.... Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298303 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 I'll spend some time going over this to understand it.... Good luck. I barely understand it myself (LOL). Actually, I understood each part as I did it, but didn't comment as I went. Some of it is kind of abstract. Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298309 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 OK, here is the code with more comments $generations = 5; //Create temp array to store results $genTableArray = array(); //Run through each column based upon the number of generations. //The column count is generation + 1 for($genCol = 0; $genCol <= $generations; $genCol++) { //Detemine the number of rows/records in the colum (1, 2, 4, 8, 16, ...) $genRowCount = pow(2, $genCol); //Detemine the rowspan for each record/row in this column //This will be the (total # rows / record in this row) //The total # of rows is based upon the number of generations to the power of 2 $rowspan = pow(2, $generations) / $genRowCount; //Run a loop for the number of records in this column for($familyGenCount=0; $familyGenCount<$genRowCount; $familyGenCount++) { //Calculate the person index to use based upon the column / row //First column has index 0, second column has 1/2, third column has 3/4/5/6, etc. //The formula is needed due to the size being dynamic $personIndex = pow(2, $genCol) + $familyGenCount - 1; //Determine the row index for this record. This is dynamic based upon the //total number of columns and the column/record beign displayed. For example, //if there are 3 generation there will be a total of 8 rows. Column 2 will have two records //So record 1 will go in the first row and record 2 will go into the 4th row $rowIndex = $rowspan * $familyGenCount; //Add the recod to the appropriate (row) in the array using the rowspan. The key of the array is the row index $genTableArray[$rowIndex][] = "<td rowspan='{$rowspan}'>$personIndex - {$familyTreeArray[$personIndex]}</td>\n"; } } //Output the array into a table //Since records weren't added to rows in order (0, 1, 2, ...) need to sort //the array by keys to get int he correct order ksort($genTableArray); $familyTreeHTML = ''; //Loop through each row in order and implode the values into an output variable foreach($genTableArray as $rowData) { $familyTreeHTML .= "<tr>\n" . implode("\n", $rowData) . "</tr>\n"; } Also, so you can understand the final process, here is what the temp array looks like before the final processing Array ( [0] => Array ( [0] => <td rowspan='8'>0 - Kegluneq Aaliyah</td> [1] => <td rowspan='4'>1 - Arctictreks Dark As Night</td> [2] => <td rowspan='2'>3 - KEBUCK SCHRIMSHANDER</td> [3] => <td rowspan='1'>7 - Pat Gagnon</td> ) [1] => Array ( [0] => <td rowspan='1'>8 - Coquette La Rouge D'Ericlam</td> ) [2] => Array ( [0] => <td rowspan='2'>4 - ARCTICTREKS CHERISH FOREVER</td> [1] => <td rowspan='1'>9 - Storm Kloud's Chosen to Win</td> ) [3] => Array ( [0] => <td rowspan='1'>10 - Arctictrek's Indiana</td> ) [4] => Array ( [0] => <td rowspan='4'>2 - Arctictrek Silver Spirit</td> [1] => <td rowspan='2'>5 - Shepherdsway Touch of Gold</td> [2] => <td rowspan='1'>11 - Outriggers Red Wolf</td> ) [5] => Array ( [0] => <td rowspan='1'>12 - Eastern Hill Coldfoot Coco</td> ) [6] => Array ( [0] => <td rowspan='2'>6 - Arctictreks Legend of a Lady</td> [1] => <td rowspan='1'>13 - Shepherdsway Phantom Scout</td> ) [7] => Array ( [0] => <td rowspan='1'>14 - Arctictrek's Indiana</td> ) ) Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298312 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 Thanks.... it will help me to understand it much more easily. I am probably taking advantage, but am I able to add an onclick into the population of the table? For example, if I generated the table, and then wanted to click on one of the dogs to bring up a new table in a new page with that dog as the root... is that possible? Can I call a function on click to post to a new page? Thanks Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298317 Share on other sites More sharing options...
Andy-H Posted December 15, 2011 Share Posted December 15, 2011 <style type="text/css"> <!-- div.tree { text-align: center; float: right; } div.clr { clear: both; } //--> </script> echo '<div>'; sort($tree, SORT_NUMERIC); $i = 1; $n = count($tree)-1; for($lvl = 0; $lvl < $n; ++$lvl) { $decendant = isset($tree[$lvl]) ? stripslashes(htmlentities($tree[$lvl], ENT_QUOTES, 'UTF-8')) : 'Unknown'; echo '<div class="tree" style="width: '. (100/pow(2, $i-1)) .'%;">'. $decendant .'</div>'; if ( (pow(2, $i-1) % $lvl) == 0 ) { echo '<div class="clr"></div>'; $i++; } } echo '</div>'; That work? Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298318 Share on other sites More sharing options...
Staggan Posted December 15, 2011 Author Share Posted December 15, 2011 The previous poster, Mjdamato gave me a working solution that works fine... thanks. This will allow me to understand how to do it so I can extend it for the functionality I am looking for... Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298320 Share on other sites More sharing options...
Psycho Posted December 15, 2011 Share Posted December 15, 2011 Can I call a function on click to post to a new page? There is only one line in that code that produces the actual output $genTableArray[$rowIndex][] = "<td rowspan='{$rowspan}'>$personIndex - {$familyTreeArray[$personIndex]}</td>\n" Put whatever other content you want in that. In this case, either put an onclick inside the TD tag or change teh content in the TD tags to a hyperlink. At the very least though, you would need to pass a value so the next page knows what dog to create the results on next. I guess you could use the name, but you should be passing an id value. But, your array doesn't contain an id, so . . . Quote Link to comment https://forums.phpfreaks.com/topic/253227-script-to-display-array-as-a-tree/#findComment-1298330 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.