Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Interactive Graphs 2

Status
Not open for further replies.

AndyApp

Programmer
Dec 20, 2001
259
GB
Does anyone know how (if possible) to create an interactive graph using ASP? When I do a search all I get is people trying to sell me their product for thousands of dollars!

Has anyone come across any tutorials or books even?

"Life is like a Ferrari, it goes to fast.
But that's ok, because you can't afford it anyway" - Jim Davis (Garfield)
 
What ind of graph are you looking for?
Bar graph, etc...

 
also noted is the closest thing to interactive you will et with asp is calling and recalling the server with links, forms etc..

the graph adjustments may be done more dynamically and efficient in javascript or another client side scripting language other then asp and then when the final changes (if need be) are doen save to whatever on one call to the server.

____________________________________________________
01001001 00100111 01110110 01100101 00100000 01100111 01101111 01110100 00100000 01000011
01101111 01100110 01100110 01100101 01100101 00100001

onpnt2.gif
 
onpnt - calls to servers etc isn't an issue plus I know far less about javascript then asp.

tarwn - would like to be able to do a line graph initially, although the chance to choose would be even better.

"Life is like a Ferrari, it goes to fast.
But that's ok, because you can't afford it anyway" - Jim Davis (Garfield)
 
Hmm, well without buying a component you have less options, though it isn't impossible. One free component that does only bar graphs is the one that BullSchmidt wrote. A search from the above search tab should turn that up as well as some older code I wrote as a pseudo-class.

I recently wrote a set of graphs for my website that would work for bar graphs, dotted line graphs, and dot graphs, but it was fairly complicated.

Basically I setup some variables for the size of the graph in the browser, then pushed all of my data into an array, keeping track of the minimum and maximum values.
Since I was dealing with temperatures I decided to define some hardcoded values for minimums and maximums, but this can be decided on the fly from the data array.

At that point you need to work out some sort of ratio between the data values and the actual size limitations from the browser. Basically this will be something like:
Code:
size_ratio = MaxHeight/(MaxFromData-MinFromData)

then in order to find heights for bars/dots/etc you would:
Code:
this_bar_ht = (data_value - MinFromData) * size_ratio

So this gives you a scaled version of the data that would be scaled to the height of your choosing. The next part is actually graphing the data.
A line graph requires one of two things, either a) a lot of data closely packed together or b) a decent amount of data with extrapolated values in between each data point.

I went with b in my graphs.
Basically what you will want to do is create a table with 1 row and a column for each bar/dot. Then you will want to loop through the data doing the above calculation and output a styled div into that bar. If you don't put a spacer bar in between the bars then you get less of a bar graph:
Code:
<%
Option Explicit

Dim MAXHEIGHT, BARWIDTH
Dim DATAMIN, DATAMAX, DATASCALE
Dim data(20), i

'Make some fake data, normally ou would get this from a db or other data storage
Randomize()
For i = 0 to UBound(data)
	data(i) = Rnd() * 1000
Next

'backto the real code, find the min/max for data
DATAMIN = data(0)
DATAMAX = data(0)
For i = 1 to UBound(data)
	if data(i) < DATAMIN Then DATAMIN = data(i)
	if data(i) > DATAMAX Then DATAMAX = data(i)
Next

'Now define the height we want the graph to be and width of the bars
MAXHEIGHT = 200

'Now find a scaled height for the data
'	we could use the DATAMIN for the min if we didn't know the theoretical data range,
'	in this case I will use 0 for a better looking graph
DATASCALE = MAXHEIGHT/DATAMAX

'---------------------------- 
' Now we output our table and graph as a bar graph
BARWIDTH = 5
Response.Write &quot;Bar Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;
For i = 0 to UBound(data)
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(i)) & &quot;px;background-color:blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
Next
response.Write &quot;</tr></table>&quot;

'---------------------------- 
' Now we output the graph as a dotted graph
BARWIDTH = 2
Response.Write &quot;<hr><br>Dotted Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;
For i = 0 to UBound(data)
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(i)) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH*3 & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
Next
response.Write &quot;</tr></table>&quot;

'---------------------------- 
' Now we output the dotted graph using interpolated data
Dim int_1, int_2, int_3

BARWIDTH = 2
Response.Write &quot;<hr><br>Interpolated Dotted Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(0)) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;

'output the rest by outputting 3 interpolated bars and then the actual data bar
For i = 1 to UBound(data)
	int_1 = data(i-1) * 3/4 + data(i) * 1/4
	int_2 = data(i-1) * 1/2 + data(i) * 1/2
	int_3 = data(i-1) * 1/4 + data(i) * 3/4
	'interpolated bars
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * int_1) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE *int_2) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * int_3) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;

	'real bar
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(i)) & &quot;px;border-top:2px solid blue;&quot;&quot;></div></td><td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' pseudo-solid graph, works better if the vertical changes are as sudden
BARWIDTH = 3
Response.Write &quot;<hr><br>Interpolated Solid Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(0)) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;

'output the rest by outputting 3 interpolated bars and then the actual data bar
For i = 1 to UBound(data)
	int_1 = data(i-1) * 3/4 + data(i) * 1/4
	int_2 = data(i-1) * 1/2 + data(i) * 1/2
	int_3 = data(i-1) * 1/4 + data(i) * 3/4
	'interpolated bars
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * int_1) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE *int_2) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * int_3) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;

	'real bar
	Response.Write &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data(i)) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' pseudo-solid graph,heavy interpolation
BARWIDTH = 1
Response.Write &quot;<hr><br>Heavily Interpolated Pseudo-Dotted-Line Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
Response.Write MakeInterpBar(data(0))

'output the rest by outputting x interpolated bars with the last one being the actual data
Dim num_interp, tval, j
num_interp = 20
For i = 1 to UBound(data)
	For j = 1 to num_interp
		tval = cInt( ( data(i-1) * (num_interp-j)/num_interp ) + ( data(i) * j/num_interp ) )
		Response.Write MakeInterpBar(tval)
	Next
Next
Response.Write &quot;</tr></table>&quot;

'a little function to output our interpolated bar and make the code cleaner
Function MakeInterpBar(data_val)
	MakeInterpBar = &quot;<td style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;><div style=&quot;&quot;width:&quot; & BARWIDTH & &quot;px;height:&quot; & cInt(DATASCALE * data_val) & &quot;px;background-color:blue;&quot;&quot;></div></td>&quot;
End Function
%>

Now the last method is probably the cleanest if you want to do interpolation. In my opinion the bar graph looks best if un-interpolated, but the dotted and solid graphs look better with moderate to heavy interpolation (respectively).

This is just an example, but it may help with what your looking to do. Of course you would have to handle getting the data into an array format yourself, and there are no numbers to specify axis values, but the general theory here should be sound.

Note: Unlike most I actually tested this script, so it should work without any problems.

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
minilogo.gif alt=tiernok.com
The never-completed website
 
It might be eaiser to read that mess if you copy and paste into a text editor or your editor of choice :)
Sorry, didn't realize how messy it was, otherwise I would have color coded it.

-Tarwn
 
Oh, and a dotted line graph is possible if you put a higher interpolation on the dotted graph and remove the spacer cells that follow each dot cell. If you want a quick example, replace the
Code:
 background-color: blue;
in the heavily interpolated graph with
Code:
 border-top:1px solid blue;

If you notice it would be possible to create a MakeBar function that basically accepts a flag for a following spacer, a flag for dot or solid, the scaled data value, and the width. It would look something like this:
Code:
Sub MakeBar(scaled_data_val, bar_width, is_solid, is_spaced,color)
   Response.Write &quot;<td style=&quot;&quot;width:&quot; & bar_width & &quot;px;&quot;&quot; valign=&quot;top&quot;>&quot;
   Response.Write &quot;<div style=&quot;&quot;width:&quot; & bar_width & &quot;px;height:&quot; & scaled_data_val & &quot;px;&quot;

   If is_solid Then
      Response.Write &quot;background-color:&quot; & color & &quot;;&quot;
   Else
      Response.Write &quot;border:&quot; & bar_width & &quot;px solid &quot; & color & &quot;;&quot;
   End If

   Response.Write &quot;&quot;&quot;></div></td>&quot;

   If is_spaced Then
      Response.Write &quot;<td style=&quot;&quot;width:&quot; & bar_width & &quot;px;&quot;&quot;></td>&quot;
   End If
End Sub

Then you would just call it with the appropriate variables and it would output your bar for you.

Note: This was on the fly, and may have some minor issues I didn't catch while writing it

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
minilogo.gif alt=tiernok.com
The never-completed website
 
Ah ha. Ok there were some errors, but here is a revamped copy of the example, it also includes a new graph, a heavily interpolated dotted graph, that looks mazingly similar to a line graph with teeny gaps:
Code:
<%
Option Explicit

'std variables
Dim MAXHEIGHT, BARWIDTH
Dim DATAMIN, DATAMAX, DATASCALE
Dim data(20), i

'some variables for interpolated graphs
Dim num_interp, tval, j

'Make some fake data, normally ou would get this from a db or other data storage
Randomize()
For i = 0 to UBound(data)
	data(i) = Rnd() * 1000
Next

'backto the real code, find the min/max for data
DATAMIN = data(0)
DATAMAX = data(0)
For i = 1 to UBound(data)
	if data(i) < DATAMIN Then DATAMIN = data(i)
	if data(i) > DATAMAX Then DATAMAX = data(i)
Next

'Now define the height we want the graph to be and width of the bars
MAXHEIGHT = 200

'Now find a scaled height for the data
'	we could use the DATAMIN for the min if we didn't know the theoretical data range,
'	in this case I will use 0 for a better looking graph
DATASCALE = MAXHEIGHT/DATAMAX

'---------------------------- 
' Now we output our table and graph as a bar graph
BARWIDTH = 5
Response.Write &quot;Bar Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;
For i = 0 to UBound(data)
	MakeBar cInt(DATASCALE * data(i)), BARWIDTH, True, True, &quot;blue&quot;
Next
response.Write &quot;</tr></table>&quot;

'---------------------------- 
' Now we output the graph as a dotted graph
BARWIDTH = 2
Response.Write &quot;<hr><br>Dotted Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;
For i = 0 to UBound(data)
	MakeBar cInt(DATASCALE * data(i)), BARWIDTH, False, True, &quot;blue&quot;
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' Now we output the dotted graph using interpolated data
num_interp = 4	'3 interpolated columns, 1 real column
BARWIDTH = 2
Response.Write &quot;<hr><br>Interpolated Dotted Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
MakeBar cInt(DATASCALE * data(0)), BARWIDTH, False, True, &quot;blue&quot;

'output the rest by outputting 3 interpolated bars and then the actual data bar
For i = 1 to UBound(data)
	For j = 1 to num_interp
		tval = cInt( ( data(i-1) * (num_interp-j)/num_interp ) + ( data(i) * j/num_interp ) )
		MakeBar cInt(DATASCALE * tval), BARWIDTH, False, True, &quot;blue&quot;
	Next
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' Heavily Interpolated Dotted Graph
num_interp = 20	'3 interpolated columns, 1 real column
BARWIDTH = 2
Response.Write &quot;<hr><br>Heavily Interpolated Dotted Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
MakeBar cInt(DATASCALE * data(0)), BARWIDTH, False, False, &quot;blue&quot;

'output the rest by outputting 3 interpolated bars and then the actual data bar
For i = 1 to UBound(data)
	For j = 1 to num_interp
		tval = cInt( ( data(i-1) * (num_interp-j)/num_interp ) + ( data(i) * j/num_interp ) )
		MakeBar cInt(DATASCALE * tval), BARWIDTH, False, False, &quot;blue&quot;
	Next
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' pseudo-solid graph, works better if the vertical changes are as sudden
num_interp = 4
BARWIDTH = 3
Response.Write &quot;<hr><br>Interpolated Solid Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
MakeBar cInt(DATASCALE * data(0)), BARWIDTH, False, False, &quot;blue&quot;

'output the rest by outputting 3 interpolated bars and then the actual data bar
For i = 1 to UBound(data)
	For j = 1 to num_interp
		tval = cInt( ( data(i-1) * (num_interp-j)/num_interp ) + ( data(i) * j/num_interp ) )
		MakeBar cInt(DATASCALE * tval), BARWIDTH, True, False, &quot;blue&quot;
	Next
Next
Response.Write &quot;</tr></table>&quot;

'---------------------------- 
' pseudo-solid graph,heavy interpolation
BARWIDTH = 1
num_interp = 20
Response.Write &quot;<hr><br>Heavily Interpolated Pseudo-Dotted-Line Graph&quot;
Response.Write &quot;<table cellpadding=&quot;&quot;0&quot;&quot; cellspacing=&quot;&quot;0&quot;&quot; style=&quot;&quot;border:1px solid #336699&quot;&quot;><tr>&quot;

'output the first bar as a starting place
MakeBar cInt(DATASCALE * data(0)), BARWIDTH, True, False, &quot;blue&quot;

'output the rest by outputting x interpolated bars with the last one being the actual data
For i = 1 to UBound(data)
	For j = 1 to num_interp
		tval = cInt( ( data(i-1) * (num_interp-j)/num_interp ) + ( data(i) * j/num_interp ) )
		MakeBar cInt(DATASCALE * tval), BARWIDTH, True, False, &quot;blue&quot;
	Next
Next
Response.Write &quot;</tr></table>&quot;

'-------------------------
' Sub to output bars
Sub MakeBar(scaled_data_val, bar_width, is_solid, is_spaced,color)
   Response.Write &quot;<td style=&quot;&quot;width:&quot; & bar_width & &quot;px;&quot;&quot; valign=&quot;&quot;bottom&quot;&quot;>&quot;
   Response.Write &quot;<div style=&quot;&quot;width:&quot; & bar_width & &quot;px;height:&quot; & scaled_data_val & &quot;px;&quot;

   If is_solid Then
      Response.Write &quot;background-color:&quot; & color & &quot;;&quot;
   Else
      Response.Write &quot;border-top:&quot; & bar_width & &quot;px solid &quot; & color & &quot;;&quot;
   End If

   Response.Write &quot;&quot;&quot;></div></td>&quot;

   If is_spaced Then
      Response.Write &quot;<td style=&quot;&quot;width:&quot; & bar_width & &quot;px;&quot;&quot;>&nbsp;</td>&quot;
   End If
End Sub
%>

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
minilogo.gif alt=tiernok.com
The never-completed website
 
Ok, wasn't quite expecting someone to completely write it for me! Thanks. So I just get the data from input boxes and put it into the data variable yes?

Thanks again. It's pretty superb, i'll try not to wreck it.

&quot;Life is like a Ferrari, it goes to fast.
But that's ok, because you can't afford it anyway&quot; - Jim Davis (Garfield)
 
Just treat that as an example and play with it a bit. I'm sure you could copme up with some improvements/change/etc. Glad it helped :)

-Tarwn

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
minilogo.gif alt=tiernok.com
The never-completed website
 
I've got a free barchart ASP class (no components) downloadable from my Web site at to help turn data stored in a table (or SQL statement) into a barchart...

Also you may want to check out the following:

Components: Graphics & Charts
Lists components.


Best regards,
J. Paul Schmidt, Freelance ASP Web Developer
ASP Design Tips, ASP Web Database Demo, Free ASP Bar Chart Tool...
 
nice, I'm glad to see someone got around to writing an SVG based graphing system...to bad I can't find a job that pays me to sit around and just dream up nifty scriptlets, otherwise I would have had one out a while ago :p

....oooh...I can do Gif/jpg graphs now, Python Imaging Library or pygame...

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
minilogo.gif alt=tiernok.com
The never-completed website
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top