QPR
asked on
read values into array
HI,
I have the following code which draws a chart to the screen and plots co-ordinates onto it. (finally spat out as a jpg to the browser).
At the moment for dev/testing purposes I am hard coding the x,y values but I need to be able to read them from an external datasource... be it a DB or xml or text file.
(code snippet)
void Page_Load(Object sender, EventArgs e) {
LineChart c = new LineChart(840, 580, Page);
c.Title="";
c.OpenFooter = "Opens";
c.CloseFooter = "Closes";
c.MidFooter = " <-------- voting days --------> ";
c.Xorigin=0; c.ScaleX=21; c.Xdivs=21;
c.Yorigin=0; c.ScaleY=25000; c.Ydivs=10;
c.AddValue(0,0);
c.AddValue(1,800);
c.AddValue(2,1100);
c.AddValue(3,2200);
c.AddValue(4,3600);
c.AddValue(5,4000);
c.AddValue(6,4105);
c.AddValue(7,5251);
c.AddValue(8,5299);
c.AddValue(9,6099);
c.AddValue(10,9090);
c.AddValue(11,12071);
c.AddValue(12,14500);
c.AddValue(13,16559);
c.AddValue(14,18222);
c.AddValue(15,18755);
c.AddValue(16,19444);
c.AddValue(17,20051);
c.AddValue(18,21222);
c.AddValue(19,21259);
c.AddValue(20,23451);
c.AddValue(21,23499);
c.Draw();
}
(/snippet)
Any ideas? I fairly new to C# so go easy on me please :)
Cheers
I have the following code which draws a chart to the screen and plots co-ordinates onto it. (finally spat out as a jpg to the browser).
At the moment for dev/testing purposes I am hard coding the x,y values but I need to be able to read them from an external datasource... be it a DB or xml or text file.
(code snippet)
void Page_Load(Object sender, EventArgs e) {
LineChart c = new LineChart(840, 580, Page);
c.Title="";
c.OpenFooter = "Opens";
c.CloseFooter = "Closes";
c.MidFooter = " <-------- voting days --------> ";
c.Xorigin=0; c.ScaleX=21; c.Xdivs=21;
c.Yorigin=0; c.ScaleY=25000; c.Ydivs=10;
c.AddValue(0,0);
c.AddValue(1,800);
c.AddValue(2,1100);
c.AddValue(3,2200);
c.AddValue(4,3600);
c.AddValue(5,4000);
c.AddValue(6,4105);
c.AddValue(7,5251);
c.AddValue(8,5299);
c.AddValue(9,6099);
c.AddValue(10,9090);
c.AddValue(11,12071);
c.AddValue(12,14500);
c.AddValue(13,16559);
c.AddValue(14,18222);
c.AddValue(15,18755);
c.AddValue(16,19444);
c.AddValue(17,20051);
c.AddValue(18,21222);
c.AddValue(19,21259);
c.AddValue(20,23451);
c.AddValue(21,23499);
c.Draw();
}
(/snippet)
Any ideas? I fairly new to C# so go easy on me please :)
Cheers
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
(note i created my connection string by dropping a OleDbConnection onto the form, created the connectionString using the IDE, copied the string to memory and deleted the non-visual component. You could do the same by droping components onto your application)
ASKER
Hi Ruff Rider.
This looks to be along the lines of what I need.
The X,Y values will be added on a daily basis... is basically a voting thing.
Each day a (non-web/tech) person will add a number via an admin page which will then cause the xml file to be opened and a new <point x=, y= /> tag to be added.... (no idea how to achieve this step but I guess that's a new question for another group! :o) where X = day numberX and Y being the number of voting papers returned as at that date (X)
Would you recommend having the required number of tags (21) with the future days being blank
Example:
<LinePoints>
<point x="1" y="100" />
<point x="2" y="450" />
<point x="3" y="612" />
<point x= y= />
<point x= y= />
...etc
</LinePoints>
or add a new line <point x= y= /> each time/day the user uses the admin page?
I see problems converting null to int32 but then I also see problems having less tags than the specified chart set-up. This probably makes little sense without seeing the code in it's entirity so I'll paste it all here in case it helps.
Continued thanks!
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Drawing" %>
<%@ Import Namespace="System.Drawing. Drawing2D" %>
<%@ Import Namespace="System.Drawing. Imaging" %>
<script language="C#" runat="server">
class LineChart
{
public Bitmap b;
public string Title="Default Title";
public string OpenFooter = "Default Footer";
public string CloseFooter="Default Footer";
public string MidFooter="Default Footer";
public ArrayList chartValues = new ArrayList();
public float Xorigin=0, Yorigin=0;
public float ScaleX, ScaleY;
public float Xdivs=2, Ydivs=2;
private int Width, Height;
private Graphics g;
private Page p;
struct datapoint {
public float x;
public float y;
public bool valid;
}
//initialize
public LineChart(int myWidth, int myHeight, Page myPage) {
Width = myWidth; Height = myHeight;
ScaleX = myWidth; ScaleY = myHeight;
b = new Bitmap(myWidth, myHeight);
g = Graphics.FromImage(b);
p = myPage;
}
public void AddValue(int x, int y) {
datapoint myPoint;
myPoint.x=x;
myPoint.y=y;
myPoint.valid=true;
chartValues.Add(myPoint);
}
public void Draw() {
int i;
float x, y, x0, y0;
string myLabel;
Pen blackPen = new Pen(Color.Blue,1);
Brush blackBrush = new SolidBrush(Color.Black);
Font axesFont = new Font("arial",10);
//first establish working area
p.Response.ContentType="im age/Gif";
g.FillRectangle(new
SolidBrush(Color.LightYell ow),0,0,Wi dth,Height );
int ChartInset = 50;
int ChartWidth = Width-(2*ChartInset);
int ChartHeight = Height-(2*ChartInset);
g.DrawRectangle(new
Pen(Color.Black,2),ChartIn set,ChartI nset,Chart Width,Char tHeight);
//must draw all text items before doing the rotate below
g.DrawString(Title, new Font("verdana",16), blackBrush, Width/2 - 290, 10);
g.DrawString(OpenFooter, new Font("Arial",8), blackBrush,Width/Width + 30, Height - 20);
g.DrawString(MidFooter,new Font("Arial",10), blackBrush,Width/2 - 50, Height - 25);
g.DrawString(CloseFooter,n ew Font("Arial",8), blackBrush,Width-65, Height - 20);
//draw X axis labels
for(i=0; i<=Xdivs; i++) {
x=ChartInset+(i*ChartWidth )/Xdivs;
y=ChartHeight+ChartInset;
myLabel = (Xorigin + (ScaleX*i/Xdivs)).ToString ();
g.DrawString(myLabel, axesFont, blackBrush, x-4, y+10);
g.DrawLine(blackPen, x, y+2, x, y-2);
}
//draw Y axis labels
for(i=0; i<=Ydivs; i++) {
x=ChartInset;
y=ChartHeight+ChartInset-( i*ChartHei ght/Ydivs) ;
myLabel = (Yorigin + (ScaleY*i/Ydivs)).ToString ();
g.DrawString(myLabel, axesFont, blackBrush, 5, y-6);
g.DrawLine(blackPen, x+2, y, x-2, y);
}
//transform drawing coords to lower-left (0,0)
g.RotateTransform(180);
g.TranslateTransform(0,-He ight);
g.TranslateTransform(-Char tInset,Cha rtInset);
g.ScaleTransform(-1, 1);
//draw chart data
datapoint prevPoint = new datapoint();
prevPoint.valid=false;
foreach(datapoint myPoint in chartValues) {
if(prevPoint.valid==true) {
x0=ChartWidth*(prevPoint.x -Xorigin)/ ScaleX;
y0=ChartHeight*(prevPoint. y-Yorigin) /ScaleY;
x=ChartWidth*(myPoint.x-Xo rigin)/Sca leX;
y=ChartHeight*(myPoint.y-Y origin)/Sc aleY;
g.DrawLine(blackPen,x0,y0, x,y);
g.FillEllipse(blackBrush,x 0-2,y0-2,4 ,4);
g.FillEllipse(blackBrush,x -2,y-2,4,4 );
}
prevPoint = myPoint;
}
//finally send graphics to browser
b.Save(p.Response.OutputSt ream, ImageFormat.Gif);
}
~LineChart() {
g.Dispose();
b.Dispose();
}
}
void Page_Load(Object sender, EventArgs e) {
LineChart c = new LineChart(840, 580, Page);
c.Title="Number of returned voting papers as at " + System.DateTime.Today.ToSt ring("dd/M M/yyyy");
c.OpenFooter = "Opens";
c.CloseFooter = "Closes";
c.MidFooter = " <-------- voting days --------> ";
c.Xorigin=0; c.ScaleX=21; c.Xdivs=21;
c.Yorigin=0; c.ScaleY=25000; c.Ydivs=10;
c.AddValue(0,0);
c.AddValue(1,800);
c.AddValue(2,1100);
c.AddValue(3,2200);
c.AddValue(4,3600);
c.AddValue(5,4000);
c.AddValue(6,4105);
c.AddValue(7,5251);
c.AddValue(8,5299);
c.AddValue(9,6099);
c.AddValue(10,9090);
c.AddValue(11,12071);
c.AddValue(12,14500);
c.AddValue(13,16559);
c.AddValue(14,18222);
c.AddValue(15,18755);
c.AddValue(16,19444);
c.AddValue(17,20051);
c.AddValue(18,21222);
c.AddValue(19,21259);
c.AddValue(20,23451);
c.AddValue(21,23499);
c.Draw();
}
</script>
This looks to be along the lines of what I need.
The X,Y values will be added on a daily basis... is basically a voting thing.
Each day a (non-web/tech) person will add a number via an admin page which will then cause the xml file to be opened and a new <point x=, y= /> tag to be added.... (no idea how to achieve this step but I guess that's a new question for another group! :o) where X = day numberX and Y being the number of voting papers returned as at that date (X)
Would you recommend having the required number of tags (21) with the future days being blank
Example:
<LinePoints>
<point x="1" y="100" />
<point x="2" y="450" />
<point x="3" y="612" />
<point x= y= />
<point x= y= />
...etc
</LinePoints>
or add a new line <point x= y= /> each time/day the user uses the admin page?
I see problems converting null to int32 but then I also see problems having less tags than the specified chart set-up. This probably makes little sense without seeing the code in it's entirity so I'll paste it all here in case it helps.
Continued thanks!
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Drawing"
<%@ Import Namespace="System.Drawing.
<%@ Import Namespace="System.Drawing.
<script language="C#" runat="server">
class LineChart
{
public Bitmap b;
public string Title="Default Title";
public string OpenFooter = "Default Footer";
public string CloseFooter="Default Footer";
public string MidFooter="Default Footer";
public ArrayList chartValues = new ArrayList();
public float Xorigin=0, Yorigin=0;
public float ScaleX, ScaleY;
public float Xdivs=2, Ydivs=2;
private int Width, Height;
private Graphics g;
private Page p;
struct datapoint {
public float x;
public float y;
public bool valid;
}
//initialize
public LineChart(int myWidth, int myHeight, Page myPage) {
Width = myWidth; Height = myHeight;
ScaleX = myWidth; ScaleY = myHeight;
b = new Bitmap(myWidth, myHeight);
g = Graphics.FromImage(b);
p = myPage;
}
public void AddValue(int x, int y) {
datapoint myPoint;
myPoint.x=x;
myPoint.y=y;
myPoint.valid=true;
chartValues.Add(myPoint);
}
public void Draw() {
int i;
float x, y, x0, y0;
string myLabel;
Pen blackPen = new Pen(Color.Blue,1);
Brush blackBrush = new SolidBrush(Color.Black);
Font axesFont = new Font("arial",10);
//first establish working area
p.Response.ContentType="im
g.FillRectangle(new
SolidBrush(Color.LightYell
int ChartInset = 50;
int ChartWidth = Width-(2*ChartInset);
int ChartHeight = Height-(2*ChartInset);
g.DrawRectangle(new
Pen(Color.Black,2),ChartIn
//must draw all text items before doing the rotate below
g.DrawString(Title, new Font("verdana",16), blackBrush, Width/2 - 290, 10);
g.DrawString(OpenFooter, new Font("Arial",8), blackBrush,Width/Width + 30, Height - 20);
g.DrawString(MidFooter,new
g.DrawString(CloseFooter,n
//draw X axis labels
for(i=0; i<=Xdivs; i++) {
x=ChartInset+(i*ChartWidth
y=ChartHeight+ChartInset;
myLabel = (Xorigin + (ScaleX*i/Xdivs)).ToString
g.DrawString(myLabel, axesFont, blackBrush, x-4, y+10);
g.DrawLine(blackPen, x, y+2, x, y-2);
}
//draw Y axis labels
for(i=0; i<=Ydivs; i++) {
x=ChartInset;
y=ChartHeight+ChartInset-(
myLabel = (Yorigin + (ScaleY*i/Ydivs)).ToString
g.DrawString(myLabel, axesFont, blackBrush, 5, y-6);
g.DrawLine(blackPen, x+2, y, x-2, y);
}
//transform drawing coords to lower-left (0,0)
g.RotateTransform(180);
g.TranslateTransform(0,-He
g.TranslateTransform(-Char
g.ScaleTransform(-1, 1);
//draw chart data
datapoint prevPoint = new datapoint();
prevPoint.valid=false;
foreach(datapoint myPoint in chartValues) {
if(prevPoint.valid==true) {
x0=ChartWidth*(prevPoint.x
y0=ChartHeight*(prevPoint.
x=ChartWidth*(myPoint.x-Xo
y=ChartHeight*(myPoint.y-Y
g.DrawLine(blackPen,x0,y0,
g.FillEllipse(blackBrush,x
g.FillEllipse(blackBrush,x
}
prevPoint = myPoint;
}
//finally send graphics to browser
b.Save(p.Response.OutputSt
}
~LineChart() {
g.Dispose();
b.Dispose();
}
}
void Page_Load(Object sender, EventArgs e) {
LineChart c = new LineChart(840, 580, Page);
c.Title="Number of returned voting papers as at " + System.DateTime.Today.ToSt
c.OpenFooter = "Opens";
c.CloseFooter = "Closes";
c.MidFooter = " <-------- voting days --------> ";
c.Xorigin=0; c.ScaleX=21; c.Xdivs=21;
c.Yorigin=0; c.ScaleY=25000; c.Ydivs=10;
c.AddValue(0,0);
c.AddValue(1,800);
c.AddValue(2,1100);
c.AddValue(3,2200);
c.AddValue(4,3600);
c.AddValue(5,4000);
c.AddValue(6,4105);
c.AddValue(7,5251);
c.AddValue(8,5299);
c.AddValue(9,6099);
c.AddValue(10,9090);
c.AddValue(11,12071);
c.AddValue(12,14500);
c.AddValue(13,16559);
c.AddValue(14,18222);
c.AddValue(15,18755);
c.AddValue(16,19444);
c.AddValue(17,20051);
c.AddValue(18,21222);
c.AddValue(19,21259);
c.AddValue(20,23451);
c.AddValue(21,23499);
c.Draw();
}
</script>
Hey,
Either way will work actually. Generating new nodes for the XML is pretty simple in .NET. However, since you say that the chart cannot deal with less than 21 days then it is better to code to suit the chart behaviour. It will mean less ahssles for you in functionality. There are a few approaches you could take:
1) Add points as they are entered.
In this case, the only points that would exist in your XML file are actual points input to the system. This would continue to work as you have it.
2) Pre-Allocate the 21 points and default their values
This approach accomodates the chart's operations. In this case, though, when adding a new entry you would have to index into the points and set teh corresponding data values.
Either way can work. Personally I would take approach one. I don't like having unused data in my system for perofrmance and resource issues. I don't know how this affects your chart though so the call is really yours :)
To help you out, have a look at the System.Xml namespace in the .NET documentation. You will find all classes you need to manipulate your xml file at runtime.
Either way will work actually. Generating new nodes for the XML is pretty simple in .NET. However, since you say that the chart cannot deal with less than 21 days then it is better to code to suit the chart behaviour. It will mean less ahssles for you in functionality. There are a few approaches you could take:
1) Add points as they are entered.
In this case, the only points that would exist in your XML file are actual points input to the system. This would continue to work as you have it.
2) Pre-Allocate the 21 points and default their values
This approach accomodates the chart's operations. In this case, though, when adding a new entry you would have to index into the points and set teh corresponding data values.
Either way can work. Personally I would take approach one. I don't like having unused data in my system for perofrmance and resource issues. I don't know how this affects your chart though so the call is really yours :)
To help you out, have a look at the System.Xml namespace in the .NET documentation. You will find all classes you need to manipulate your xml file at runtime.
ASKER
Getting there!
Man C# is picky when you come from a VB background (not a bad thing tho) XML != Xml
ok "Could not find file "C:\WINNT\system32\GraphDa ta.xml""
The xml file is in the same folder as the aspx
In ASP classic (VBScript) I would use server.mapPath. How can I achieve this in C#.
Hopefully, after 2 forgotten ; and 10 upper/lower case errors :)
Also.... how can I paste text as plain text into VS.Net? When I paste from here I get font declarations etc... I see no paste special on the menu.
And.... Why is there no Intellisense? Is this because I am doing aspx as opposed to a vb.net file?
Man C# is picky when you come from a VB background (not a bad thing tho) XML != Xml
ok "Could not find file "C:\WINNT\system32\GraphDa
The xml file is in the same folder as the aspx
In ASP classic (VBScript) I would use server.mapPath. How can I achieve this in C#.
Hopefully, after 2 forgotten ; and 10 upper/lower case errors :)
Also.... how can I paste text as plain text into VS.Net? When I paste from here I get font declarations etc... I see no paste special on the menu.
And.... Why is there no Intellisense? Is this because I am doing aspx as opposed to a vb.net file?
ASKER
works like a charm and I learnt stuff into the bargain (always a bonus!)
I've used the absolute file path to the xml file and doubled up on the backslashes but would still like a relative path to it if possible?
Now to learn how to open/append the xml file/child tags
Many thanks
Jay
I've used the absolute file path to the xml file and doubled up on the backslashes but would still like a relative path to it if possible?
Now to learn how to open/append the xml file/child tags
Many thanks
Jay
Hey QPR,
For the MapPath, have a look at the System.Web.UI.Page object. It has a method called MapPath() that may be what you are looking for.
As for the text pasting, I'm not sure why that happens. Try pasting in notepad text file then paste from there. You should have intellisense when you are editing code. I don't think IntelliSense operates on the actual aspx page editor. You should have it when editing the code behind the aspx page though.
For the MapPath, have a look at the System.Web.UI.Page object. It has a method called MapPath() that may be what you are looking for.
As for the text pasting, I'm not sure why that happens. Try pasting in notepad text file then paste from there. You should have intellisense when you are editing code. I don't think IntelliSense operates on the actual aspx page editor. You should have it when editing the code behind the aspx page though.
ASKER
Thanks I'll have a look at MapPath() thanks.
Yep I'll revert to that, starnge that the IDE doesn't offer paste options though.
From memory this page/code was originally an aspx example I d/l as a zip file which I then just opened in VS.NET... as a result I can't find any code behind etc.
Only ever opened as a single file as opposed to a project/solution. Maybe that explains the lack of intellisense.
Many thanks for all the help RR.
Yep I'll revert to that, starnge that the IDE doesn't offer paste options though.
From memory this page/code was originally an aspx example I d/l as a zip file which I then just opened in VS.NET... as a result I can't find any code behind etc.
Only ever opened as a single file as opposed to a project/solution. Maybe that explains the lack of intellisense.
Many thanks for all the help RR.
using System.Data.OleDb;
System.Data.OleDb.OleDbCon
System.Data.OleDb.OleDbCom
DBconnection = new OleDbConnection();
DBconnection.ConnectionStr
try
{
DBconnection.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.Messa
}
listBox1.Items.Clear();
string Sql = "SELECT field1 FROM table1"; //SQL select statement
DbSelect = new OleDbCommand(Sql, DBconnection); //create my command using the sql string connection using the db connection
DbSelect.Prepare(); // tell the sql server to prepare the statement
OleDbDataReader myReader = DbSelect.ExecuteReader(); // create a "datareader" which will read rows from the results
try
{
while (myReader.Read()) // while there is data in the returned rows
{
listBox1.Items.Add(myReade
}
}
finally
{
myReader.Close();
}