Click to See Complete Forum and Search --> : PHP Timeline Generator
idgarad
12-18-2003, 11:34 AM
Attached is a sample of code I wrote to generate an automatic timeline similar to a gantt chart. As a fiction write I have tons of hand penciled timelines that can span thousands of years. Most project software is not geared towards handling historic timelines. There are some bugs including large expanses of time (colspans greater than 1000). The full source is attached including a phpPgAdmin SQL dump of the table structure I am using. I am leaving the description vague intentionally to see if I commented the code well. This is the actual code that generates the time line there are several other components. Send me an IM via ICQ if you want the whole DIR. I am not a programmer by trade so I hope this is what a person would expect for code. Again if you want to try out the code IM me and i'll transfer it. There are still some bugs to be worked out, I just want to check so far if the coding style is acceptable as this is my first public and complex php project. The key file is the timeline4.php file. The others are just utility files to enter data in. (Be careful to make sure no event spans more then 4 years as I having figured out what IE's maximum colspan limit is). The ..\dbconn.php just dumps the $db into the pgconnect(). File not included for DB security.
idgarad
12-23-2003, 05:38 PM
Now tinkering with rendering the table into a PNG file to improve rendering. So far trying to formulate a variable wrapping point by taking the pre-rendered data and chopping them into atomic year events with the following format:
Event Name(orginal): Test Event
Start : 2/1950
End: 3/1955
After the data parse we end up with
Test Event: 2/1950 to 12/1950
(cont.) Test Event: 1/1951 to 12/1951
(cont.) Test Event: 1/1952 to 12/1953
(cont.) Test Event: 1/1953 to 12/1954
(cont.) Test Event: 1/1955 to 3/1955
This happens in the pre-render phase. When rendering a definable span is set in years (say 2) and the render builds the first table (1950 to 1951) and scans for events translating the month into an X cordinate and GD rendering the event. If two events (50 and 51) exist on the same table ignore rendering the second entires' name thus making them appear one contigious bar on the chart. Does this seem to be an effective solution to wrapping a table into various timeline charts? I am concerned with catalogging long term events that span 3000+ years. At 20 pixels per month in width a few tests I ran resulted in a few pngs 4 million pixels wide. To aleeviate this I intended to break the table (effectivly creating a word wrap effect for timelines). The only other solution was framing the full width image in memory and generating a chopped up version of it via output. Am I heading down the wrong path on handling the chart generation?
ednark
01-04-2004, 01:19 PM
the code looks clean and understandable...
I would however like to point out: you do not have to recall dbconn.php every time you would like to run a query...
you need only make one connection for the script executing... you _can_ reestablish the connection each time, but that is a waste... once at the top of the file is enough...
you may remove all but the first:
$db=$PRIMARY_DATABASE;
include '../dbconn.php';
or better yet, the first call should be:
$db=$PRIMARY_DATABASE;
include_once('../dbconn.php');
that way if another file also wants dbconn.php, then the system will only do the first one, which is all you need
hope this sheds some light... other wise I think the code is well commented, once I get it running with my DB i may have further comments
drawmack
01-04-2004, 02:21 PM
Ed that signature is sick
ednark
01-04-2004, 03:05 PM
drawmack: how do you spell depth-first? :)
idgarad: next critique...
a useful trick when dealing with large chuncks of HTML you need to...
more here >> print
print <<<ARBITRARY_STRING
"anything in here can be writting without escaping double quote"
"this" "makes" 'writing' 'html' 'much' 'easier'
you don't even need to put in \n new lines
you can even use $variables in here $arr[$index]
ARBITRARY_STRING;
LordShryku
01-04-2004, 03:57 PM
Originally posted by ednark
or better yet, the first call should be:
$db=$PRIMARY_DATABASE;
include_once('../dbconn.php');
This brings out a question: Why would you use include instead of require? Maybe it's just me, but in the cases where I was including a file(like a database connection file), I needed it. So, instead of using include_once, I always use require_once. Am I alone in this thinking?
ednark
01-04-2004, 04:50 PM
LordShryku: your right... require/require_once should probably be used for things that are mandatory... however i don't think ive seen someone ever try to include() a file that may or may not be there...
a quick summary:
when successful include() and require() do exactly the same thing
when include() fails it throws a warning, which may simply be ignored, and the script continues to execute
when require() fails it throws a fatal error, and the scripts halts all processing
so LordShryku is right... you should probably change your include()s to require()s
Next item: bringing global variables into the function scope: i see you ahve run into and made your own solution.
you have created the getVariables.php file to include. this works perfectly, but right now this method is not too useful... only because it does not do any error correction. You do look to see if the variable is in $_GET but if it isn't you are taking no steps to fix it. Again your code works, but since this is the critique forum ill say this
so I would recommend, on failure of finding the wanted $_GET[var] that you either:
1) die and print an error message
2) set the wanted variable to a default value <prob not what you want to do>
3) return to where they came from to try again with the trick:
die(header("Location: http://www.blah.com/"));
also if you took my advise and put one call in each file for $db.. that means you would have to bring that variable from the global to the local scope for each function you want to use it..
this is easliy done this way
$db = pg_connect("blah");
function blah () {
global $db;
}
<probably more critiques to come>
idgarad
01-05-2004, 01:02 AM
Where I am coding this they use the dbconn.php file similar to a function reading the local scope $db as certain complex queries result in
........................................................
$db=whosOnFirst();
include dbconn.php;
$query="select * from names";
$r1=pgquery($query);
$db=whosOnSecond();
include dbconn.php;
$query="select * from names";
$r2=pgquery($query);
etc..
........................................................
Just force of habit I guess. It really should be a function as I look at it. I guess the devs at work just don't like functions (in fact I am the only one that uses functions. I used to be a C\C++ programmer as a hobby.)
P.S. Update I have gotten the graphics lib up and running but am still hammering out how to wrap the table into chunks and do some primitive collission detection on the Plinko fill concept. I am trying to get the system to effectivly "wrap" the timeline table by chopping the table up into 10 year chunks. Still a couple of weeks to go for a PNG format. Hopefully that will address the rendering time problems with huge timelines (my testbed has 2000 year history and takes IE 4 hours to render with 100+ megs of RAM. obviously moving to a graphical format is going to be necessary for the scope I am trying for. Also apps like photoshop do not treat PNG files wideth then 100,000 pixels wide well either so I am going to have to break up the image in some fashion. Again I am thinking of trying to get variable render settings like defined spans for each image (1, 10 , 100 year spans.) Hopefully this turns out well I am sure that there are fiction nuts out there that could use a good database driven timeline tool for Sci-Fi and Fantasy writing.
Thank you for the feedback so far much appreciated.
PHP Builder
Copyright WebMediaBrands Inc. All Rights Reserved.