StockPicker.aspx:
Sub ChartBTN_Click (Sender As Object, E AS Eventargs)
Chart.ImageURL = "ImageGenerator_vb.aspx?"
Chart.visible = TRUE
For i = 0 to stocks.Items.count-1
IF (stocks.items (i) .selected = true) THEN
Chart.imageurl = chart.imageurl & "Symbols =" & stocks.Items (i) .value & "&"
END IF
NEXT
End Sub
script>
MSFT asp: listitem>
Sun asp: listitem>
asp: checkboxlist>
form>
body>
html>
ImageGenerator_vb.aspx:
<% @ Page language = "vb" ContentType = "image / jpeg"%>
<% @ Import namespace = "system.drawing"%>
<% @ Import namespace = "system.drawing.drawing2d"%>
<% @ Import namespace = "system.drawing.imaging"%>
<% @ Import namespace = "chartgenerator"%>
<% @ Outputcache duration = "10"%>
Function GetStockDetails (Symbol As String) As ChartLine
Dim MyChartline As New Chartline
IF (Symbol = "MSFT") THEN
DIM stockValues () as single = {60, 110, 120, 180, 185, 190, 240, 290}
MyChartLine.Width = 5mychartline.color = color.blue
MyChartline.LineStyle = dashstyle.solid
MyChartline.title = "Microsoft Corp. (MSFT)"
MyChartline.symbol = "msft"
MyChartline.values = stockValues
Return mychartline
Elseif (Symbol = "Sun") THEN
DIM stockValues () as single = {180, 155, 125, 60, 25, 15, 10, 3}
MyChartLine.Width = 5
mychartline.color = color.red
MyChartline.LineStyle = dashstyle.dot
MyChartline.title = "Sun Corp. (Sun)"
MyChartline.symbol = "sun"
Return Nothing
END FUNCTION
SUB Page_Load (Sender As Object, E as Eventargs)
'Generate Chart Data for Image ....
DIM xaxes () as string = {"9:00 am", "10:00 am", "11:00 am", "1:00 pm", "1:30 pm"}
Dim MyChartData As New ChartData
MyChartData.yticksize = 20
Mychartdata.ymax = 250
Mychartdata.ymin = 0
MyChartData.xaxistitles = xaxes
DIM Symbols () as string = request.queryString.getValues ("Symbols")
IF (not symbols = nothing) THEN
For i = 0 to symbols.length-1
DIM stockValue as chartline = getStockDetails (Symbols (i) .tolower)
IF (stockValue <> Nothing) THEN
MychartData.Lines.Add (stockValue)
'Create In-Memory Bitmap of JPEG
Dim mychartengine as new charTenne
Dim stockbitmap as bitmap = mychartEngine.drawchart (600, 400, mychartdata)
'Render Bitmap Stream Back to Client
Stockbitmap.save (response.outputstream, imageformat.jpeg)
ChartEngine.cs:
Using system.winforms;
Using system.collections;
Using system.collections.bases; using system.drawing;
Using system.drawing.drawing2d;
Using system.drawing.image;
Using system.componentmodel;
Using system;
Using system.io;
Namespace chartgenerator {
// Core Line Data Structure
Public struct linedata {
Public float [] linevalues;
Public String LineTitle;
Public String LineSymbol;
}
// Line Data Plus Display STYLE Information
Public class chartline {
PRIVATE color LINECOLOR;
PRIVATE LINEDATA LINEDATA;
PRIVATE DashStyle Lines;
Private int lineWidth;
// conntructors
Public chartline (): base () {}
Public Chartline (Linedata Linedata): Base () {
THISLINEDATA = Linedata;
// Properties
Public color color color {
Get {return linecolor;
Set {linecolor = value;}
Public dashstyle lineestyle {
Get {return.
Set {lineestyle = value;}
Public string symbol {
Get {return linedata.linesymbol;
Set {linedata.linesymbol = value;
Public String Title {
Get {return linedata.linetitle;
Set {linedata.linetitle = value;
Public float [] values {
Get {return linedata.linevalues;}
Set {lineData.LineValues = Value;
Public int width {
Get {return linewidth;}
Set {linewidth = value;}
//Methods
Public void setlinedata (linedata linedata) {
//Chart Data Structure
Public class chartdata {
Private float ytyicksize;
PRIVATE FLOAT YMAX;
PRIVATE FLOAT YMIN;
PRIVATE STRING [] Xaxistitles;
Private chartlinelist lines = new chartlinelist ();
Private color gridcolor = color.blue;
PRIVATE BOOL Showhgridlines = true;
Private bool showvgridlines = true;
Public float ytyicksize {
Get {return ytyicksize;}
Set {ytyicksize = value;}
PUBLIC FLOAT YMAX {
Get {return ymax;}
Set {ymax = value;}
Public float ymin {
Get {return}
SET {ymin = value;}
Public String [] xaxistitles {
Get {return xaxistitles;
Set {xaxistres = value;}
Public chartlinelist lines {
Get {return line;}
Set {lines = value;
Public color gridcolor {
Get {return gridcolor;
Set {gridcolor = value;}
Public bool showhgridlines {
Get {return showhgridlines;
Set {showhgridlines = value;
Public bool showvgridlines {
Get {return showvgridline;}
Set {showvgridlines = value;
// Collection of Chart Lines
Public class chartlinelist: typedcollectionbase {
Public chartline this [int index] {
Get {
Return (ChartLine) (ListLine);
SET {
List [Index] = Value;
Public int Add (chartline value) {
Return List.Add (Value);
Public void insert (int index, chartline value) {
List.Insert (Index, Value);
Public int indexof (chartline value) {
Return List.indexof (Value);
Public Bool Contains (Chartline Value) {
Return List.Contains (Value);
Public void remove (chartline value) {
List.remove (Value);
Public void copyto (chartline [] array, int index) {
List.copyto (array, index);
// Charting Engine - Draws a Chart Based on the Given ChartData
Public class chartengine {
Private chartdata chartdata;
PRIVATE FLOAT LEFT;
PRIVATE FLOAT RIGHT;
PRIVATE FLOAT TOP;
Private float bottom;
PRIVATE FLOAT TICKCOUNT;
PRIVATE FLOAT YCOUNT;
Private float hspacing;
Private float vspacing;
Private graphics g;
Private reccTangle R;
Private Color Backcolor;
Private Color Forecolor;
PRIVATE FONT BASEFONT
Private font legendfont; private reccTanglef legendRect;
Public chartEngine () {
Public Bitmap Drawchart (int Width, Int Height, Chartdata Chartdata) {
Bitmap Newbitmap = New Bitmap (Width, Height, Pixelformat.Format32bppargb);
Graphics g = graphics.FromImage (newbitmap);
Rectangle R = New Rectangle (0, 0, Width, Height);
Color myforecolor = color.black;
Color mybackcolor = color.white;
Font Myfont = New Font ("Arial", 10);
THIS.DRAWCHART (G, R, MybackColor, MyForeColor, MyFont, Chartdata);
Return newbitMap;
Public Void Drawchart (Graphics G, Rectangle R, Color Backcolor, Color Forecolor, Font Basefont, Chartdata Chartdata) {
this.ChartData = ChartData;
THIS.G = g;
THIS.R = R;
THIS.BACKCOLOR = Backcolor;
THIS.FORECOLOR = Forecolor;
this.basefont = basefont;
This.LegendFont = New font (basefont.size * 2/3), basefont.style | fontstyle.bold;
g.smoothingmode = smoothingmode.antialias;
Calculatechartdimensions ();
DrawBackground ();
INTERNALDRAWCHART ();
Private void calculatechartdimensions () {
Right = r.width - 5;
TOP = 5 * basefont.size;
Bottom = r.height - basefont.size * 2;
Tickcount = chartdata.ymin;
Ycount = (chartdata.ymax-chartdata.ymin) / chartdata.yticksize;
HSPACING = (bottom-top) / ycount;
vSpacing = (right) / chartdata.xaxistitles.LENGTH;
// Left Depends on Width of Text - for Simplicity Sake Assume That Largest Yvalue Is The Biggest
// Take Into Account The First X Axis Title
FLOAT MAXYTEXTSIZE = G.MeasureString (ChartData.ymax.toT7tring (), BaseFont) .width;
Float firstxtXtitle = g.measureString (chartdata.xaxistitles [0], basefont) .width;
Left = (MAXYTEXTSIZE> FirstxtXtitle)? maxytextsize: firstxtXtitle; Left = R.X LEFT 5;
// Calculate Size of Legend Box
Float maxlegendwidth = 0;
Float maxlegendheight = 0;
// Work out size of biggest legend
Foreach (chartline cl in chartdata.line) {
FLOAT CurrentWidth = g.measureString (cl.title, legendfont) .width;
Float currentheight = g.MeasureString (cl.title, legendfont) .height;
MaxLegendWidth = (MAXLEGENDWIDTH> CURRENTWIDTH)? MAXLEGENDWIDTH: CURRENTWIDTH;
MaxLegendHeight = (MaxLegendheight> CurrentHeight)? MaxLegendHeight: Currentheight;
LegendRect = New Rectanglef (R.X 2, R.Y 2, MaxLegendWidth 25 5, (MaxLegendHeight 2) * ChartData.Lines.count) 3);
Private void drawbackground () {
Lineargradientbrush B = New LineargradientBrush (r, color.steelblue, backcolor, lineargradientmode.horizontal);
G.FillRectangle (B, R);
b.dispose ();
Private vidinaldrawchart () {
DrawGrid ();
Drawline (CL);
Drawlegend ();
// Draw Time on Chart
String TimeString = "generated:" DateTime.now.tolongTimeString ();
Sizef textsize = g.MeasureString (TimeString, BaseFont);
g.drawstring (TimeString, Basefont, New Solidbrush (Forecolor), R.Width - Textsize.width - 5, Textsize.height * 2/3);
Private void drawgrid () {
Pen Gridpen = New Pen (chartdata.gridcolor);
// Vertical - Include Tick Desc's
IF (chartdata.showvgridlines) {
For (int i = 0; (vSpacing * i) FLOAT X = Left (vSpacing * i); String desc = chartdata.xaxistitles [i]; g.drawline (Gridpen, X, TOP, X, Bottom (Basefont.size * 1/3)); Sizef Textsize = G.MeasureString (DESC, BASEFONT); G.DrawString (Desc, BaseFont, New Solidbrush (ChartData.GridColor), X (Textsize.width / 2), Bottom (BaseFont.Size * 2/3)))) ; } } // Horizontal IF (chartdata.showhgridlines) { For (Float I = Bottom; I> Top; I- = HSPACing) { String desc = tickcount.tostring (); Tickcount = chartdata.yticksize; G. Drawline (Gridpen, Right, I, LEFT-3, I); SIZEF TEXTSIZE = G.MeasureString (DESC, BASEFONT); G. DrawString (DESC, BASEFONT, New Solidbrush (ChartData.Gridcolor), Left-Textsize.width - 3, I - (Textsize.Height / 2); } } } Private void Drawline (Chartline Chartline) { Pen Linepen = new Pen (chartline.color); Linepen.startcap = linecap.Round; Linepen.endcap = linecap.Round; Linepen.width = chartline.width; Linepen.dashstyle = Chartline.LinesTyle; Pointf [] Values = New Pointf [chartline.values.length]; Float scale = hspacing / chartdata.yticksize; For (int i = 0; i FLOAT X = Left vSpacing * i; Values [i] = new pointf (x, bottom-chartline.values [i] * scale); } g.drawlines (Linepen, Values); } Private vid drawlegend () { // Draw Legend Box ControlPaint.drawborder (G, Rectangle) LegendRect, SystemColors.WindowFrame, ButtonBorderstyle.Solid; Lineargradientbrush B = New Lineargradientbrush (LegendRect, Backcolor, Color.Steelblue, lineargradientmode.horizontal); R.INFLATE (-1, -1); G.FillRectangle (B, LegendRect); b.dispose (); FLOAT STARTY = 5; Foreach (chartline cl in chartdata.line) { Pen P = New Pen (cl.color); p.Width = p.width * 4; Sizef textsize = g.measureString (cl.title, legendfont); Float liney = starty textsize.height / 2; g.drawline (p, r.x 7, liney, r.x 25, liney); g.drawstring (Cl.Title, Legendfont, New Solidbrush (Forecolor), R.X 30, Starty; Starty = (TextSize.height 2); } } } }
FLOAT X = Left (vSpacing * i);
String desc = chartdata.xaxistitles [i];
g.drawline (Gridpen, X, TOP, X, Bottom (Basefont.size * 1/3));
Sizef Textsize = G.MeasureString (DESC, BASEFONT); G.DrawString (Desc, BaseFont, New Solidbrush (ChartData.GridColor), X (Textsize.width / 2), Bottom (BaseFont.Size * 2/3)))) ;
// Horizontal
IF (chartdata.showhgridlines) {
For (Float I = Bottom; I> Top; I- = HSPACing) {
String desc = tickcount.tostring ();
Tickcount = chartdata.yticksize;
G. Drawline (Gridpen, Right, I, LEFT-3, I);
SIZEF TEXTSIZE = G.MeasureString (DESC, BASEFONT);
G. DrawString (DESC, BASEFONT, New Solidbrush (ChartData.Gridcolor), Left-Textsize.width - 3, I - (Textsize.Height / 2);
Private void Drawline (Chartline Chartline) {
Pen Linepen = new Pen (chartline.color);
Linepen.startcap = linecap.Round;
Linepen.endcap = linecap.Round;
Linepen.width = chartline.width;
Linepen.dashstyle = Chartline.LinesTyle;
Pointf [] Values = New Pointf [chartline.values.length];
Float scale = hspacing / chartdata.yticksize;
For (int i = 0; i FLOAT X = Left vSpacing * i; Values [i] = new pointf (x, bottom-chartline.values [i] * scale); } g.drawlines (Linepen, Values); } Private vid drawlegend () { // Draw Legend Box ControlPaint.drawborder (G, Rectangle) LegendRect, SystemColors.WindowFrame, ButtonBorderstyle.Solid; Lineargradientbrush B = New Lineargradientbrush (LegendRect, Backcolor, Color.Steelblue, lineargradientmode.horizontal); R.INFLATE (-1, -1); G.FillRectangle (B, LegendRect); b.dispose (); FLOAT STARTY = 5; Foreach (chartline cl in chartdata.line) { Pen P = New Pen (cl.color); p.Width = p.width * 4; Sizef textsize = g.measureString (cl.title, legendfont); Float liney = starty textsize.height / 2; g.drawline (p, r.x 7, liney, r.x 25, liney); g.drawstring (Cl.Title, Legendfont, New Solidbrush (Forecolor), R.X 30, Starty; Starty = (TextSize.height 2); } } } }
FLOAT X = Left vSpacing * i;
Values [i] = new pointf (x, bottom-chartline.values [i] * scale);
g.drawlines (Linepen, Values);
Private vid drawlegend () {
// Draw Legend Box
ControlPaint.drawborder (G, Rectangle) LegendRect, SystemColors.WindowFrame, ButtonBorderstyle.Solid;
Lineargradientbrush B = New Lineargradientbrush (LegendRect, Backcolor, Color.Steelblue, lineargradientmode.horizontal);
R.INFLATE (-1, -1);
G.FillRectangle (B, LegendRect);
FLOAT STARTY = 5;
Pen P = New Pen (cl.color);
p.Width = p.width * 4;
Sizef textsize = g.measureString (cl.title, legendfont);
Float liney = starty textsize.height / 2; g.drawline (p, r.x 7, liney, r.x 25, liney);
g.drawstring (Cl.Title, Legendfont, New Solidbrush (Forecolor), R.X 30, Starty;
Starty = (TextSize.height 2);