Forum Moderators: coopster

Message Too Old, No Replies

PHP/MySQL graphical hit-counter

Anyone good at algebra?

         

Patrick Taylor

4:13 am on Aug 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



With the help of contributors of this forum I've built a PHP/MySQL-driven hit counter that presents the results both numerically and in the form of a graphical barchart that automatically adds a row with each day that passes.

Although it works fine, I'm not quite there yet: the final hurdle. The programming part of it is now okay - I'm just a bit stuck with some basic algebra. The way it works is this:

For the bar, I have a rectangular image in a table cell. Its height is fixed but its width ($bar_width) is determined by the hits for any particular day, thus:


$bar_width = ((($row['dailies'] / $total) * 100) * $e_factor2);
// Display the rows
echo '<tr><td width="200" valign="top"><p class="text1a">' . $row['info_date_formatted'] . ':</p></td><td width="70" valign="top"><p class="text1a">' . $row['dailies'] . '</p></td><td width=" " valign="top" bgcolor="' . $color_id . '"><p class="bar"><img src="bar.jpg" height="11" width="' . $bar_width . '%" /></td></tr>';

$row_dailies is the hits for any particular day and $total is the total hits, so (($row['dailies'] / $total) * 100) gives a percentage that can be transferred to the physical width of the bar in the table cell containing the bar image.

The problem has been that with each day, the number of rows increases and so the bar width has been getting shorter and shorter - still mathematically a correct daily expression of the proportion of total hits but divided by an increasing number of days... on some days not even wide enough to show, and eventually it will stop showing at all for any day.

So I'm trying to work out a method for automatically expanding the width of the bar by a factor determined by the increasing number of days: the variable $e_factor2 above. I got to $e_factor2 as follows:


// Calculate base expansion factor
$e_factor1 = (1 + ($row_count / 100));
// Adjusted base expansion factor
$e_factor2 = ($e_factor1 * 10);

This works too. $e_factor1 obviously increases each day - if there are 47 days of hits, $e_factor1 is 1.47 and it will go up day by day. $e_factor2 is just a tenfold multiplication - a visual judgement so the expansion can actually be seen on the page.

The issue I still have is that there really should be some algebraic logic to $e_factor1. Ideally the bar for the day with the most number of hits would always be, say, 80% of the table cell (always leaving a bit of visual whitespace to its right) even if there were 10,000 days of records. All the other days would fall into line at a smaller width, but the "maximum hit day bar-width" would remain at 80%. And this needs to be irrespective of the size of the user's screen, otherwise it would be simple to make the bar a fixed width of pixels - my bar width has to be percentage-based.

What should my formula be for calculating the adjusted width of the bar - my $e_factors? I appreciate that this is rather off the beaten track, but I'm happy to pass on how I've done this so far (an URL in a sticky?) if anyone is interested in making their own PHP/MySQL hit-counting bar-graph...

RonPK

2:09 pm on Aug 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This won't answer your question, but when I made my own PHP/MySQL hit-counting bar-graph, I had the width of the bars relate to the number of hits on the busiest day.

So, if your bar table is 200px wide, and the hits per day are like this:
day 1: 50
day 2: 100
day 3: 75

the width of the bars would be (hits/maxhits)*200 :
day 1: 100px
day 2: 200px
day 3: 150px

Patrick Taylor

3:07 pm on Aug 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the suggestion. My page is a fluid one, so the bar image widths need to be (i) a percentage of the total hits and (ii) a percentage of the variable width cell that contains them (with the biggest day's hits always around 80% of the cell width). I have it looking reasonably well but I can't work out if my formula is logically correct or not... it was more by trial and error. As each day passes, a small increment is added to all the bar widths to compensate for the extra day that would otherwise shorten them (the total being divided by more days), but getting this algebraically correct (as well as visually okay) is beyond me so far.

ergophobe

4:21 pm on Aug 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



then how about

(hits/maxhits)*80

Won't that work just as well?

Patrick Taylor

8:14 am on Aug 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Well no, because it gives a bar length according to the hits on a day in relation to total hits. And that's the issue - the bars get shorter and shorter as days are added. They have to be incrementally adjusted upwards in length on a daily basis. It doesn't really matter - what I've done will do for now and I will see how it goes. Thanks for the suggestion anyway.

Regards,

Patrick

RonPK

8:43 am on Aug 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



> hits on a day in relation to total hits

IMHO that number doesn't make much sense. After a while, all numbers will get close to zero. Maybe there is a multiplier trick to pump up the bars, but (again IMHO) it's much easier to use the day number in relation to number of hits on the busiest day. Gives you a nice graph in which you can easily see whether traffic is going up or down over time.

Patrick Taylor

10:30 am on Aug 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



the day number in relation to number of hits on the busiest day

That makes sense, though I don't know how to capture that number. Assuming I did capture it, I would also need to work out a way to use this number to set the bar width for that particular day at, say, 80% of the cell width, and for all the other daily totals to fall into line.

So at present I'm using a pump-method (mentioned above) and the bargraph looks very good, but because - and I keep saying this (I ain't got the brains) - it isn't done with a logically correct algebraic formula, in time it will most likely need manual adjustment, which is less than completely satisfying (in other words the concept doesn't work properly).

Patrick Taylor

1:41 am on Aug 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Trying to capture the highest day's score. In the above example I have used, in my "while" loop:


// Print highest day's hits
echo max($row['dailies']);

I just get a "wrong parameter count" error. Why is this? In the PHP documentation it says:


max() returns the numerically highest of the parameter values

If I use:


echo max(array($row['dailies']));

... I get a printout of the whole set of numbers in the array all strung together.

RonPK

10:17 am on Aug 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



max($a, $b, $c) will compare a b and c and return the highest value. So max() needs more then 1 parameter.

Try something like this to get the highest value from the result set:

$maxhits = 0; 
while ($row = mysql_fetch_assoc($your_result_set)) {
if ($row['dailies'] > $maxhits) $maxhits = $row['dailies'];
}

You will need to reset the pointer before looping through the result set again, with mysql_data_seek().

I hope this helps!

Patrick Taylor

10:50 am on Aug 23, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




mysql_data_seek()

Damn! Never heard of it until now. Just looked it up on the PHP website... "thinks... should I give this up or should I persevere?"

Seriously, thanks for the suggestion!