Pozdrav
Klasa nije jos zavrsena, a kada ce - ne znamo

Trenutno sam u nekoj frci-panici, pa ce ovo morati da priceka bolje dane.
Uglavnom, ima ono sta trazis .... pa manje vise. Klasa za sada radi samo sa jedno-dimenzionalnim nizom, ali nije prosto da ubacis da vrednosti za ordinatu
uzimas iz drugog clana niza.
Da pokrenes, napravi jedan panel (ili bilo koji drugi objekat kome mozes uzeti GDI handle) i pozoves konstruktor:
Code:
chart = new CChartDraw(panel1.CreateGraphics(),
panel1.Width, panel1.Height);
i da na nekom eventu (npr. button click) pokrenes sa metodom StartAnimation();
Posto klasa crta po Bitmap objektu, uz malo dorade mozes da osvezavas sliku na OnPaint eventu.
Code:
#define ANIMATION
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Collections;
#if DEBUG
using System.Diagnostics;
#endif
namespace ChartDraw
{
public class CChartDraw
{
private System.Drawing.Graphics gSurface;
private Bitmap surface;
private int border_size;
private Color border_color = Color.White, body_color = Color.LightGray, grid_color = Color.Black,
line_color = Color.Blue;
private bool draw_grid = false, draw_coordinates = false;
private float line_size = 1;
private Size area;
#if ANIMATION
private Point pStart, pEnd;
private Timer tmr;
private int eCounter = 0;
long min = 0, max = 0;
private float kx=0, ky=0;
private ArrayList valuesArray;
private float line_kx, line_ky;
private int steps, stepCounter;
private Bitmap bmp;
#endif
#region Constructors
public CChartDraw()
{
surface = new Bitmap(16, 16);
gSurface = Graphics.FromImage(surface);
border_size = 0;
}
public CChartDraw(int x, int y)
{
surface = new Bitmap(x, y);
gSurface = Graphics.FromImage(surface);
border_size = 0;
}
public CChartDraw(Graphics g,int width, int height)
{
gSurface = g;
surface = null;
border_size = 0;
area = new Size(width, height);
#if ANIMATION
pStart = new Point(0,0);
pEnd = new Point(0,0);
#endif
}
#endregion
public float LineSize
{
get
{
return line_size;
}
set
{
line_size = value;
}
}
public Color LineColor
{
get
{
return line_color;
}
set
{
line_color = value;
}
}
public Color GridColor
{
get
{
return grid_color;
}
set
{
grid_color = value;
}
}
public Color BorderColor
{
get
{
return border_color;
}
set
{
border_color = value;
}
}
public Color BodyColor
{
get
{
return body_color;
}
set
{
body_color = value;
}
}
public bool DrawGrid
{
get
{
return draw_grid;
}
set
{
draw_grid = value;
}
}
public bool DrawCoordinates
{
get
{
return draw_coordinates;
}
set
{
draw_coordinates= value;
}
}
public int BorderSize
{
get
{
return border_size;
}
set
{
border_size = value;
}
}
public void ApplyChart(Graphics g)
{
if(surface != null){
g.DrawImage(surface, 0, 0);
g.Flush();
}
}
public void DrawChart(ArrayList arr)
{
#if !ANIMATION
long min = 0, max = 0;
float kx=0, ky=0;
#endif
int elements = 0;
int xs = 0, ys = area.Height ;
foreach(object o in arr)
{
if((int)o > max) max = (int)o;
if((int)o < min) min = (int)o;
elements++;
}
if(elements > 0)
{
kx = (float)(area.Width - (border_size<<1))/elements;
ky = (float)(area.Height - (border_size<<1))/(max-min);
}
gSurface.FillRectangle(new SolidBrush(border_color),0,0, area.Width, area.Height);
gSurface.FillRectangle(new SolidBrush(body_color), border_size, border_size,
area.Width - (border_size<<1), area.Height - (border_size<<1));
if(draw_grid)
{
// TODO grid
}
if(draw_coordinates)
{
gSurface.DrawLine(new Pen(new SolidBrush(Color.Black), 2), border_size,
area.Height + (min * ky) - border_size,
area.Width - border_size,
area.Height + (min * ky) - border_size);
}
elements = 0;
xs = border_size;
ys = area.Height - border_size;
foreach(object o in arr)
{
gSurface.DrawLine(new Pen(line_color, line_size),xs,ys,
(xs=(int)(elements*kx)+border_size),
(ys=area.Height - (int)((int)o * ky) - border_size + (int)(min*ky)));
elements++;
}
}
private void PrepareBackground()
{
}
#if ANIMATION
public void StartAnimation(ref ArrayList arr, int interval)
{
int elements = 0;
valuesArray = arr;
foreach(object o in valuesArray)
{
if((int) o > max) max = (int) o;
if((int) o < min) min = (int) o;
elements++;
}
if(elements > 0)
{
kx = (float) (area.Width - (border_size<<1))/elements;
ky = (float) (area.Height - (border_size<<1))/(max-min);
}
tmr = new Timer();
tmr.Interval = interval;
tmr.Tick += new EventHandler(tmr_Tick);
bmp = new Bitmap(area.Width, area.Height, gSurface);
eCounter = 1;
stepCounter = -1;
pStart.X = border_size; // TODO zameni se sa drugim clanom niza
pStart.Y = area.Height - (int) ((int) valuesArray[0]*ky) - border_size + (int) (min*ky);
tmr.Start();
}
private void tmr_Tick(object sender, EventArgs e)
{
int lenX, lenY;
int x, y;
if(stepCounter >= steps)
{
stepCounter = -1;
eCounter++;
pStart.X = pEnd.X;
pStart.Y = pEnd.Y;
}
if(eCounter >= valuesArray.Count)
{
((Timer) sender).Stop();
return;
}
if(stepCounter < 0)
{
pEnd.X = (int) (eCounter*kx) + border_size; // TODO isto zameniti sa drugim clanom niza :)
pEnd.Y = area.Height - (int) ((int) valuesArray[eCounter] * ky) - border_size + (int) (min*ky);
lenX = (pEnd.X - pStart.X);
lenY = (pEnd.Y - pStart.Y);
// HACK Hmmmmmmmmmmm
steps = (lenX<0)?lenX*-1:lenX;
if(steps < ((lenY<0)?lenY*-1:lenY)) steps=((lenY<0)?lenY*-1:lenY);
line_kx = (float)lenX/steps;
line_ky = (float)lenY/steps;
stepCounter = 0;
}
x = ((int)(stepCounter * line_kx)) + pStart.X;
y = ((int)(stepCounter * line_ky)) + pStart.Y;
bmp.SetPixel(x,y, line_color);
if((stepCounter&0x1) > 0) gSurface.DrawImage(bmp, 0,0);
stepCounter++;
}
#endif
}
}
Ako bude nekih problema, slobodno pitaj