Solved

read values into array

Posted on 2004-08-22
9
338 Views
Last Modified: 2008-03-10
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
0
Comment
Question by:QPR
  • 4
  • 3
  • 2
9 Comments
 
LVL 3

Accepted Solution

by:
ruff_ryder earned 250 total points
Comment Utility
Assuming you have your points in a nXML file with the following structure:

<LinePoints>
     <point x="1" y="2" />
     <point x="3" y="4" />
     <point x="5" y="6" />
</LinePoints>

then you could read them back as follows in C#:

XmlDocument configXml = new XmlDocument();
configXml.Load("myxmlfile.xml");
                  
XmlNodeList topLevelSections = configXml.GetElementsByTagName("LinePoints");
if( topLevelSections.Count <= 0 )
      return;

foreach(XmlNode child in topLevelSections[0].ChildNodes)
{
      if( child.Name != "point" )
            continue;

      c.AddValue( Convert.ToInt32(((XmlAttribute)child.Attributes.GetNamedItem("x")).Value),
                          Convert.ToInt32(((XmlAttribute)child.Attributes.GetNamedItem("y")).Value) );
}


Ofcourse you would put all that code in a try-catch block
0
 
LVL 4

Expert Comment

by:ErikPhilips
Comment Utility
(MS Access DB access via OleDB)

using System.Data.OleDb;

System.Data.OleDb.OleDbConnection DBconnection;  //connection to database
System.Data.OleDb.OleDbCommand    DbSelect;      // command to send to DB

DBconnection = new OleDbConnection();
DBconnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Password=\"\";User ID=Admin;Data Source=C:\\Database.mdb;Mode=Share Deny None;Extended Properties=\"\";Jet OLEDB:System database=\"\";Jet OLEDB:Registry Path=\"\";Jet OLEDB:Database Password=\"\";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password=\"\";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False";
try                              
{
      DBconnection.Open();
}
catch (Exception ex)
{
      Console.WriteLine(ex.Message);
}

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(myReader.GetString(0));  // reader get column 0 as a string, add it to the listbox
      }
}
finally
{
      myReader.Close();
}

0
 
LVL 4

Expert Comment

by:ErikPhilips
Comment Utility
(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)
0
 
LVL 29

Author Comment

by:QPR
Comment Utility
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="image/Gif";
g.FillRectangle(new
SolidBrush(Color.LightYellow),0,0,Width,Height);
int ChartInset = 50;
int ChartWidth = Width-(2*ChartInset);
int ChartHeight = Height-(2*ChartInset);
g.DrawRectangle(new
Pen(Color.Black,2),ChartInset,ChartInset,ChartWidth,ChartHeight);

//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,new 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*ChartHeight/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,-Height);
g.TranslateTransform(-ChartInset,ChartInset);
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-Xorigin)/ScaleX;
      y=ChartHeight*(myPoint.y-Yorigin)/ScaleY;
      g.DrawLine(blackPen,x0,y0,x,y);
      g.FillEllipse(blackBrush,x0-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.OutputStream, 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.ToString("dd/MM/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>

0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:ruff_ryder
Comment Utility
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.
0
 
LVL 29

Author Comment

by:QPR
Comment Utility
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\GraphData.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?
0
 
LVL 29

Author Comment

by:QPR
Comment Utility
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
0
 
LVL 3

Expert Comment

by:ruff_ryder
Comment Utility
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.
0
 
LVL 29

Author Comment

by:QPR
Comment Utility
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.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now