GDI+绘制曲线图的难点

wsg9913028 2009-12-17 10:50:15
大家好,利用.NET中GDI+可以手动绘制图形,现在我利用GDI+在绘制曲线图
(1)坐标点X和Y的值是从数据库取出,然后在坐标系中标点连线就行

我有如下问题:
(1)坐标系统如果去绘制(也就是X轴和Y轴),X轴和Y轴的范围和间隔
(2)坐标点(X和Y值)是按照什么样比例在坐标系中找点呢
请各位发表下意见,谢谢
...全文
201 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
-汪帆- 2009-12-17
  • 打赏
  • 举报
回复
我认为坐标系统应该是预先定义好的,坐标点应该有度量单位,也就不存在比例的问题了。
wsg9913028 2009-12-17
  • 打赏
  • 举报
回复

int ChartInset = 50;
int ChartWidth = Width - (2 * ChartInset);
int ChartHeight = Height - (2 * ChartInset);
g.DrawRectangle(new Pen(Color.Black, 1), ChartInset, ChartInset, ChartWidth, ChartHeight);
//写出图片上面的图片内容文字
g.DrawString(Title, new Font("arial", 14), blackBrush, Width / 3, 10);

//沿X坐标写入X标签
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);
}
//沿Y坐标写入Y标签
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);
}


x0 = ChartWidth * (prevPoint.x - Xorigin) / ScaleX;
y0 = ChartHeight * (prevPoint.y - Yorigin) / ScaleY;
x = ChartWidth * (myPoint.x - Xorigin) / ScaleX;
y = ChartHeight * (myPoint.y - Yorigin) / ScaleY;


这些代码具体代表什么意思,是不是画曲线图都要用到这个公式
wartim 2009-12-17
  • 打赏
  • 举报
回复
自动根据坐标点的增多和峰值调整绘制曲线



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication231
{
public partial class Form1 : Form
{
PictureBox PB = new PictureBox();
Bitmap Bmp = null;
List<int> Ys = new List<int>();
Random R = new Random();

public Form1()
{
InitializeComponent();

PB.Parent = this;
PB.Dock = DockStyle.Fill;

this.ClientSize = new Size(300+25, 300);
Bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);

Timer T = new Timer();
T.Interval = 100;
T.Tick += new EventHandler(T_Tick);
T.Enabled = true;
}

void T_Tick(object sender, EventArgs e)
{
Ys.Add(R.Next(5000) - 5000 / 2);

if (Ys.Count < 2)
return;

int[] Temp =Ys.ToArray();
Array .Sort (Temp );

double XS = (Bmp.Width - 25) * 1.0 / Ys.Count;
double YS = (Bmp.Height)*1.0 / (Temp[Temp.Length -1]*2) ;

using (Graphics G = Graphics.FromImage(Bmp))
{
G.Clear(Color.Black);

G.DrawLine(Pens.White, new Point(0, Bmp.Height / 2), new Point(Bmp.Width, Bmp.Height / 2));
G.DrawLine(Pens.White, new Point(25, 0), new Point(25, Bmp.Height));

List<PointF> Points = new List<PointF>();

for (int i = 0; i < Ys.Count; i++)
{
Points.Add(new PointF((float)(i * XS + 25), (float)(Ys[i] * YS) + Bmp.Height / 2));
}

G.DrawCurve(Pens.Red, Points.ToArray());
}

PB.Image = Bmp;
}
}
}

wsg9913028 2009-12-17
  • 打赏
  • 举报
回复
欢迎大家进来讨论
wsg9913028 2009-12-17
  • 打赏
  • 举报
回复

int ChartInset = 50;
int ChartWidth = Width - (2 * ChartInset);
int ChartHeight = Height - (2 * ChartInset);
g.DrawRectangle(new Pen(Color.Black, 1), ChartInset, ChartInset, ChartWidth, ChartHeight);
//写出图片上面的图片内容文字
g.DrawString(Title, new Font("arial", 14), blackBrush, Width / 3, 10);

//沿X坐标写入X标签
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);
}
//沿Y坐标写入Y标签
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);
}




x0 = ChartWidth * (prevPoint.x - Xorigin) / ScaleX;
y0 = ChartHeight * (prevPoint.y - Yorigin) / ScaleY;
x = ChartWidth * (myPoint.x - Xorigin) / ScaleX;
y = ChartHeight * (myPoint.y - Yorigin) / ScaleY;


这些代码具体代表什么意思,是不是画曲线图都要用到这个公式
han42959 2009-12-17
  • 打赏
  • 举报
回复
坐标系统预先定义好,坐标点有度量单位.也会出现问题
wsg9913028 2009-12-17
  • 打赏
  • 举报
回复
下面是一个画曲线图的实例:
public class LineChart
{
public Bitmap b;
public string Title = "在ASP.NET中实现数据图表";
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;
}
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, 2);//定义画笔
Brush blackBrush = new SolidBrush(Color.Black);//定义画刷
Font axesFont = new Font("arial", 10);//定义字体

//首先要创建图片的大小
p.Response.ContentType = "image/jpeg";
g.FillRectangle(new SolidBrush(Color.LightGreen), 0, 0, Width, Height);
int ChartInset = 50;
int ChartWidth = Width - (2 * ChartInset);
int ChartHeight = Height - (2 * ChartInset);
g.DrawRectangle(new Pen(Color.Black, 1), ChartInset, ChartInset, ChartWidth, ChartHeight);
//写出图片上面的图片内容文字
g.DrawString(Title, new Font("arial", 14), blackBrush, Width / 3, 10);
//沿X坐标写入X标签
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);
}
//沿Y坐标写入Y标签
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);
}
g.RotateTransform(180);
g.TranslateTransform(0, -Height);
g.TranslateTransform(-ChartInset, ChartInset);
g.ScaleTransform(-1, 1);

//画出图表中的数据
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;
}

//最后以图片形式来浏览
b.Save(p.Response.OutputStream, ImageFormat.Jpeg);

}

public void Dispose()
{
g.Dispose();
b.Dispose();
}
}

代码中红色部分代表什么意思呀
wuyq11 2009-12-17
  • 打赏
  • 举报
回复
winform中的坐标轴方向完全相反:窗体的左上角为原点(0,0),水平向左则X增大,垂直下向则Y增大
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Red, 2);
g.DrawLine(p, 10, 10, 100, 100);
g.DrawRectangle(p, 10, 10, 100, 100);//起始坐标为(10,10),宽为,高为
g.DrawEllipse(p, 10, 10, 100, 100);//画椭圆,起始坐标为(10,10)
}
hhc123 2009-12-17
  • 打赏
  • 举报
回复
Y
|
|
|
|
|
|
|
|
|__1__2__3__4__5__6__7__8__9__10_______________________X
要画个给你看吧
ludeli2004 2009-12-17
  • 打赏
  • 举报
回复
这个范围和间隔应该是根据你的需求设置
wsg9913028 2009-12-17
  • 打赏
  • 举报
回复
定义坐标系统有什么具体规则吗,能否说的详细一点,谢谢

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧