";
echo $_POST['query2']." is query 2";
echo " ";
// echo "this is the raw data ";
// echo $_POST['dataset'];
// ARRAY STRUCTURE REFERENCE
// -------------------------
// this script uses several arrays with specific organizations they are structured as follows
// $unique[keys are names of unique concepts provided from the dataset][array ordered as and consisting of xpos, ypos keys. this array is associative where xpos is the coordinate number for the x axis ] ; this is a 2d array example: $unique[gold][ypos] = 1; this is the y axis position of the unique concept gold in the matrix
// $concepts[keys are names of primary concepts provided by the dataset][array of unique concepts that were associated with primary concept keys] ; this is a 2d array example: $concepts[gold] = array(shiny, valuable, metal); this is a list of the subject compliments attributed to the primary concept gold
// $queryXlist[entries are remaining concepts to be processed from the root query tree] this is a 1d array example: $queryXlist[0] = "gold"
// $queryXtotalconcepts[entries consist of the complete list of unique concepts stemming from the root query] this is a 1d array, there are two of these arrays each produced from their respective query these two arrays are compared to find common unique concepts shared between the two query trees
// I have left all of my commented echo debugging statements in the code so if you want to work with this application uncomment them to see the text output
// POPULATE QUERYLIST ARRAYS
// -------------------------
$query1list[] = $_POST['query1'];
$query1list[] = "deg1";
$query2list[] = $_POST['query2'];
$query2list[] = "deg1";
// OPEN OUTPUT FILE AND ADD HEADER
// -------------------------------
$datestamp = date("U"); // this retrieves epoch time in seconds
$datestamp = strval($datestamp); // changes the datestamp int value to a str value
$datestamp = trim($datestamp); // removes any unwanted spaces
$cscpname = "compound_subject_compliment_path_".$_POST['query1']."_".$_POST['query2']."_".$datestamp.".svg"; // this will interject that string of seconds
echo " ";
// echo $cscpname." is the output SVG filename.";
echo " ";
$cscp = fopen($cscpname, "a"); // opens the output file for appending
echo "Right click this link and save link target as to download this SVG file! ";
fwrite($cscp, // this writes the svg header info to the output file and provides a fixed x,y that coorosponds to the viewbox. this will help in preventing page view anamolies, i am using 3000 because it will give space for a lot of unique concepts to be included in the matrix and provide sufficient resolution across the matrix for aftermarket SVG output possibilities
"
" // this rect element is the grey background of the SVG output
);
fclose($cscp);
// DATASET INTAKE, CONCEPTS ARRAY CREATION
// -------------------------------------------------
$dataexploded = $_POST['dataset'];
$dataexploded = str_replace("\r", "\n", $dataexploded); // converts all linebreaks to "\n" type
$dataexploded = preg_replace( "/(\\n)+/", "\n", $dataexploded); // reduces any number of repititious "\n"'s to one "\n"
$dataexploded = explode("\n", $dataexploded); // breaks dataset string into an array of line strings based on the linebreaks
$concepts = array(); // create concepts array
foreach ($dataexploded as $currentarray) { // look at each string in the datasetexploded array
$subarray = explode(",", $currentarray); // split the current dataset string on its ","'s
$keyname = $subarray[0];
// echo " ".$keyname." is the $subarray[0] element ";
foreach ($subarray as $sub) {
$subtrimmed = trim($sub); // this trims off any excess space charactors from the front and end of each array entry
// echo $subtrimmed." ";
$uniquelist[] = $subtrimmed; // this puts the current concept into the uniquelist array for tracking of total concepts
$concepts[$keyname][] = $subtrimmed; // make a new array entry in the concepts array, key the new array by its first entry and fill it with the current arrays values
}
// echo " ";
// echo $concepts[$keyname][0]." is the 0 position of the above sub array and the value that will be unset it should be the same as the above key ";
unset($concepts[$keyname][0]); // remove the redundant subject complement that is in the 0 position of the new concepts array
}
// echo " ";
// foreach ($concepts as $key => $value) {
// echo " ".$key." is the key of the array ";
// foreach ($concepts[$key] as $subvalue) {
// echo $subvalue." is a value from the concepts[$key] array ";
// }
// }
// echo "this is the uniquelist ";
$uniquelist = array_unique($uniquelist); // this removes any duplicate values from the unique list of concepts
// foreach ($uniquelist as $value) {
// echo "$value ";
// }
// MATRIX ITTERATOR, UNIQUE ARRAY CREATION
// ------------------------------------------
$unique = array(); // create unique array
$uniquecount = count($uniquelist); // count the number of entries in the array
// echo " the number of unique concepts in the dataset is $uniquecount ";
$matrixsqr = sqrt($uniquecount); // get the square root of that number
$matrixsqr = floor($matrixsqr) + 1; // remove any trailing decimal places and round up to accomodate a matrix point for all the unique concepts in the dataset
$matrixspacer = 3000 / $matrixsqr; // this creates a number of points to use to multiply the coordinate value by to produce equal spacing of concepts along the axis of the putput matrix (3000 is the default x,y "viewbox" attribute number written into the svg header)
$matrixspacer = $matrixspacer - 50;
// echo " the matrixspacer value is $matrixspacer ";
// this next nested for loop is creating the matrix positions for each unique concept in the dataset. the xpos value will be rewritten befor the output is made to create the leveled branching tree shape of the image
reset($uniquelist); // sets the array pointer to the first index position
for ( $x = 1; $x <= $matrixsqr; $x += 1) { // this is a nested for loop that makes the coordinate matrix grid
for ( $y = 1; $y <= $matrixsqr; $y += 1) {
// echo " ";
$thisconcept = current($uniquelist); // all arrays in php have a global pointer position that is monitored during the running of a script, this pointer can be moved and is helpful in loops this statement using the "current" array position call
// echo $thisconcept;
$xrand = rand(35, 2970);
$yrand = rand(35, 2970);
$unique[$thisconcept] = array(xpos => $xrand, ypos => $yrand, placed => 0); // this is a nested itterator that builds a random matrix of 2d coordinate positions and stores these coordinates in an array with a unique concept as a key for each pair. the "placed" array value is where I keep track of if this unique concept has been found during the course of searching a query tree and if so makes sure not to rewrite its xpos location initialy it is 0
// echo current($uniquelist)." ";
// echo $unique[$thisconcept][xpos]. " the x position ";
// echo $unique[$thisconcept][ypos]. " the y position ";
//unset(current($uniquelist)); // this removes the 0 position from the uniquelist array allowing the rest of the entries to move down presenting a new 0 position for the next itteration
next($uniquelist); // this moves the array pointer to the next index position for the start of the next itteration
// echo count($unique)." ";
}
}
$matrixstep = 500; // this is the interval distance that will be moved down the output image at each of the degrees of seperation
$unique[$_POST['query1']][xpos] = 100; // this places the starting query unique concept matrix location to 100 points from the top of the display rectangle not changing its rand ypos
$unique[$_POST['query2']][xpos] = 100;
$unique[$_POST['query1']][placed] = 1; // the placed array value of 1 tells the script that the xpos value has been fixed and should be used and not reasigned
$unique[$_POST['query2']][placed] = 1;
// echo " ";
// echo " unique array values ";
$cscp = fopen($cscpname, "a"); // opens the output file for appending
fwrite($cscp, // this writes a bold circle around query 1's expanded x,y
""
);
fwrite($cscp, // this writes a bold circle around query 2's expanded x,y
""
);
// EXECUTION OF QUERYS
// -------------------
// there is a problem with tracking the level of degrees away from the query because once you travel away from the first level of compliments you cant distuinguish the level you are at from the query1list of concepts
// BY APPENDING A CODED STRING ENTRY AS AN ARRAY ELEMENT IN THE ARRAY AT CERTIAN POINTS IN THE WHILE LOOP THE SETS OF UNIQUE CONCEPTS THAT ARE ADDED TO THE QUERY1LIST CAN BE LEVELED BY DEGREE. ITHINK THIS CAN BE DONE BY PUTTING A DEG1 STRING ON TO THE THE END OF THE ARRAY AFTER THE QUERY1 CONCEPT AND THEN WHEN THE WHILE LOOP GETS TO THE DEG1 ENTRY THE SCRIPT WILL HAVE ALREADY ADDED MORE CONCEPTS TO THE LIST AND WHEN IT GETS TO THE DEG1 IT WILL ADD A DEG2 TO THE END OF THE ARRAY LIST AND IN THIS FASHION I CAN LOOK FOR A DEGX AND QUIT OUT OF THE LOOP
$numdeg1 = 1; // this var will be a count of the levels of degrees away from the query concept the script has traveled
reset($query1list);
while (current($query1list) != null) { // this looks at the current querylist to see if it has values to process, once the pointer gets to the end of the array it will return null and exit, this works because I add the new items to test to the end of the array ahead of the current pointer
if ($numdeg1 > 4) { // this if statement looks to see if the number of degrees away from the query has become to large and if so will finish out the master while loop
next($query1list);
} elseif (current($query1list) == "deg1") { //check to see if there is a degree delimiting entry string for the current array entry
$numdeg1 = $numdeg1 + 1; // this increments the degree level count
$query1list[] = "deg1"; // this puts a new degree level delimiting entry string at the end of the queryxlist array
next($query1list);
}
if (in_array(current($query1list), $query1totalconcepts)) { // this tests to see if i have processed this concept already this avoids infinite loops
next($query1list);
} else {
$query1totalconcepts[] = current($query1list);
$q1tcfull[] = current($query1list);
if (array_key_exists(current($query1list), $concepts)) { // this tests to see if the current concept has a primary concept value because if so lines will need to be drawn to that primary concepts subject compliments
$cscp = fopen($cscpname, "a"); // opens the output file for appending
$keyname = current($query1list); // this puts the current concept into a string var for use later
if($unique[$keyname][placed] == 0){ // this if statement checks to see if the xpos value has been moved to a new position based on the level of degree away from the query in the tree if the value is a 0 then the xpos has not been altered and should be
$movexpos = $matrixstep * $numdeg1; // this produces a number by multiplying the matrixstep by the current number of degrees from the concept to make the stepped look of the output
$unique[$keyname][xpos] = $movexpos; // this assigns the new value to the xpos of the unique concept
$unique[$keyname][placed] = 1; // setting the placed value to 1 will ensure that when the script finds this concept again it will not move its position a second time
}
$startx = $unique[$keyname][xpos]; // these two statements put the x and y position into vars for plotting the start of the lines to be drawn
$starty = $unique[$keyname][ypos]; // the x and y position is multiplied by the matrix expanding number to get the final positions for display
foreach ($concepts[current($query1list)] as $subarr) { // this will itterate through all of the subject compliments in the current array
if($unique[$subarr][placed] == 0){ // this if statement checks to see if the xpos value has been moved to a new position based on the level of degree away from the query in the tree if the value is a 0 then the xpos has not been altered and should be
$movexpos = $matrixstep * $numdeg1; // this produces a number by multiplying the matrixstep by the current number of degrees from the concept to make the stepped look of the output
$unique[$subarr][xpos] = $movexpos; // this assigns the new value to the xpos of the unique concept
$unique[$subarr][placed] = 1; // setting the placed value to 1 will ensure that when the script finds this concept again it will not move its position a second time
}
$endx = $unique[$subarr][xpos]; // these two statements put the x and y position into vars for plotting the end of the lines to be drawn
$endy = $unique[$subarr][ypos]; // the x and y position is multiplied by the matrix expanding number to get the final positions for display
fwrite($cscp, // this will write out an SVG line from the expanded matrix position of the current primary concept to the current subject compliments expanded matrix position
" "
);
$query1list[] = $subarr; // this will populate the query1list array with a possible primary concept for checking
$q1tcfull[] = $subarr; // these next two lines put the current concept into an array that will track the total set of all concepts primary or not for later comparison
$q1tcfull = array_unique($q1tcfull); // this statement weeds out and duplicate entries in this array
}
} else {
next($query1list);
}
//next($query1list);
}
}
$numdeg2 = 1;
reset($query2list);
while (current($query2list) != null) {
if ($numdeg2 > 4) { // this if statement looks to see if the number of degrees away from the query has become to large and if so will finish out the master while loop
next($query2list);
} elseif (current($query2list) == "deg1") {
$numdeg2 = $numdeg2 + 1;
$query2list[] = "deg1";
next($query2list);
}
if (in_array(current($query2list), $query2totalconcepts)) {
next($query2list);
} else {
$query2totalconcepts[] = current($query2list);
$q2tcfull[] = current($query2list);
if (array_key_exists(current($query2list), $concepts)) {
$cscp = fopen($cscpname, "a");
$keyname = current($query2list);
if($unique[$keyname][placed] == 0){
$movexpos = $matrixstep * $numdeg2;
$unique[$keyname][xpos] = $movexpos;
$unique[$keyname][placed] = 1;
}
$startx = $unique[$keyname][xpos];
$starty = $unique[$keyname][ypos];
foreach ($concepts[current($query2list)] as $subarr) {
if($unique[$subarr][placed] == 0){
$movexpos = $matrixstep * $numdeg2;
$unique[$subarr][xpos] = $movexpos;
$unique[$subarr][placed] = 1;
}
$endx = $unique[$subarr][xpos];
$endy = $unique[$subarr][ypos];
fwrite($cscp,
" "
);
$query2list[] = $subarr;
$q2tcfull[] = $subarr;
$q2tcfull = array_unique($q2tcfull);
}
} else {
next($query2list);
}
//next($query2list);
}
}
// foreach ($q1tcfull as $q1tc) {
// echo $q1tc;
// }
// foreach ($q2tcfull as $q2ct) {
// echo $q2ct;
// }
$intersection = array_intersect($q1tcfull, $q2tcfull); // find common unique concepts between the two query trees
$cscp = fopen($cscpname, "a"); // opens the output file for appending
foreach ($intersection as $common) {
//echo $common;
fwrite($cscp, // this writes the current x,y position of the unique concept from the unique array into the output file as a magenta circle
""
);
foreach ($concepts as $key => $arrayvalues) { // this foreach looks at all of the values in the arays in the concepts array and compares these subarray values to the common concepts in the intersection array and then draws lines back from the intersection values to any primary concepts
if (in_array($common, $concepts[$key]) == true) {
$startx = $unique[$common][xpos];
$starty = $unique[$common][ypos];
$endx = $unique[$key][xpos];
$endy = $unique[$key][ypos];
fwrite($cscp, // this draws a line from the subject compliment to its primary concept as a dotted magenta line
" "
);
fwrite($cscp, // this writes a circle at the primary concept which the current concept is a subject compliment of
""
);
}
}
}
// POPULATE MATRIX
// ---------------
$cscp = fopen($cscpname, "a");
foreach ($unique as $key => $value) { // this foreach loop writes SVG output for each of the matrix points that have an associated unique concept
// echo $key." is the key for the following concept coordinates ";
$name = $key;
fwrite($cscp, // this writes the current x,y position of the unique concept from the unique array into the output file
""
);
if (in_array($key, $intersection)) {
fwrite($cscp, // this writes the current name of the unique concept from the unique array into the output file
"".$name." "
);
} else if ($key == $_POST['query1']) {
fwrite($cscp, // this writes the current name of the unique concept from the unique array into the output file
"".$name." "
);
} else if ($key == $_POST['query2']) {
fwrite($cscp, // this writes the current name of the unique concept from the unique array into the output file
"".$name." "
);
} else {
fwrite($cscp, // this writes the current name of the unique concept from the unique array into the output file
"".$name." "
);
}
// echo $unique[$key][xpos]." ";
// echo $unique[$key][ypos]." ";
}
// ADD FOOTER TO SVG OUTPUT
// ------------------------
$cscp = fopen($cscpname, "a"); // opens the output file for appending
fwrite($cscp, // this writes the svg footer info to the output file, the footer has the rights statement and the graph key
"This image was created by Pointsware, which is developed and maintained by Jeremiah Colonna-Romano at http://www.jeremiahcolonnaromano.com/pointsware.php
The Pointsware software and source code is licensed under Creative Commons BY-NC-SA with all rights and restrictions.
Query 1 tree
Query 2 tree
Common to both
Shows link between a common and any of its primary concepts
"
);
fclose($cscp);
// OUTPUT TO SCREEN
// ----------------
$svgoutput = file_get_contents("http:\/\/www.jeremiahcolonnaromano.com\/".$cscpname);
echo " ";
echo ""
?>