62,041
社区成员
发帖
与我相关
我的任务
分享
class CFXChart
{
public class DataPoint
{
public DateTime sj { get; set; }
public int value { get; set; }
}
public class DrawItem
{
public string Title { get; set; }
public Color Color { get; set; }
public int Max { get; set; }
public int Min { get; set; }
public List<DataPoint> DataPoints { get; set; }
public DrawItem(string title, Color color, IEnumerable<DataPoint> datapoints)
{
Title = title;
Color = color;
DataPoints = datapoints.ToList();
Max = DataPoints.Select(x => x.value).Max();
Min = DataPoints.Select(x => x.value).Min();
int newMax = (Max - Min) / 10;
int newMin = -(Max - Min) / 10;
if (newMax < 2) newMax = 2;
if (newMin > -2) newMin = -2;
Max += newMax;
Min += newMin;
}
}
public List<DrawItem> DrawItems { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public CFXChart(int width, int height, params DrawItem[] data)
{
Width = width;
Height = height;
DrawItems = new List<DrawItem>();
foreach (var item in data)
DrawItems.Add(item);
}
private void FillBlank(Graphics g)
{
g.Clear(Color.White);
}
private void DrawTitle(Graphics g, string title)
{
var titlesize = g.MeasureString(title, new Font("宋体", 14));
g.DrawString(title, new Font("宋体", 14), Brushes.Black, new PointF((float)((Width - titlesize.Width) / 2.0), (float)(Height * 0.06)));
}
private void DrawBody(Graphics g, RectangleF rect, DateTime dt1, DateTime dt2)
{
g.DrawRectangle(Pens.Black, rect.X+40.0f, rect.Y, rect.Width-40.0f, rect.Height-40.0f);
float x = rect.X;
float y = rect.Y;
int n = 15 / this.DrawItems.Count;
if (n <= 1) n = 2;
for (int i = 0; i <= n; i++)
{
y = rect.Y + i * (rect.Height - 40.0f) / (float)n;
if (i != n && i != 0)
g.DrawLine(new Pen(Color.Gray, 0.5f), new PointF(rect.X + 40.0f, y), new PointF(rect.X + rect.Width, y));
foreach (var item in this.DrawItems)
{
g.DrawString(((item.Max - item.Min) * (1 - i / (float)n) + item.Min).ToString("0.00"), new Font("宋体", 8), new SolidBrush(item.Color), new PointF(x, y - 5.0f));
y += 10.0f;
}
}
g.DrawLine(new Pen(Color.Black, 2.0f), new PointF(rect.X + 40.0f, ywarn), new PointF(rect.X + rect.Width, ywarn));
n = 8;
for (int i = 0; i <= n; i++)
{
x = rect.X + 40.0f + i * (rect.Width - 40.0f) / (float)n;
if (i != n && i != 0)
g.DrawLine(new Pen(Color.Gray, 0.5f), new PointF(x, rect.Y), new PointF(x, rect.Y + rect.Height - 40.0f));
double totals = new TimeSpan(dt2.Ticks - dt1.Ticks).TotalSeconds;
DateTime tlabel = dt1.AddSeconds(totals / (double)n * (i));
string timelabel = tlabel.ToString("HH:mm");
//if (i != 0)
g.DrawString(timelabel, new Font("宋体", 8), Brushes.Black, new PointF(x - 12.0f, y + 5.0f));
}
foreach (var item in this.DrawItems)
{
float dv = rect.Top + (item.Max - item.DataPoints[0].value) / (float)(item.Max - item.Min) * (rect.Height - 40.0f);
float dt = rect.Left + 40.0f + (float)(new TimeSpan(item.DataPoints[0].sj.Ticks - dt1.Ticks).TotalSeconds) / (float)(new TimeSpan(dt2.Ticks - dt1.Ticks).TotalSeconds) * (rect.Width - 40.0f);
for (int i = 1; i < item.DataPoints.Count; i++)
{
float dv1 = rect.Top + (item.Max - item.DataPoints[i].value) / (float)(item.Max - item.Min) * (rect.Height - 40.0f);
float dt11 = rect.Left + 40.0f + (float)(new TimeSpan(item.DataPoints[i].sj.Ticks - dt1.Ticks).TotalSeconds) / (float)(new TimeSpan(dt2.Ticks - dt1.Ticks).TotalSeconds) * (rect.Width - 40.0f);
g.DrawLine(new Pen(item.Color, 1.0f), new PointF(dt, dv), new PointF(dt11, dv1));
dv = dv1;
dt = dt11;
}
}
}
private void DrawLegend(Graphics g, RectangleF rect)
{
float x = rect.X + 10;
float y = rect.Y + 10;
foreach (var item in this.DrawItems)
{
g.DrawString(item.Title, new Font("宋体", 8), Brushes.Black, new PointF(x, y));
x += 35.0f;
g.DrawLine(new Pen(item.Color, 2.0f), new PointF(x, y + 5.0f), new PointF(x + 10.0f, y + 5.0f));
x += 25.0f;
}
}
public Bitmap MakeChart()
{
DateTime mintm = DrawItems.Select(x => x.DataPoints.Select(y => y.sj).Min()).Min();
DateTime maxtm = DrawItems.Select(x => x.DataPoints.Select(y => y.sj).Max()).Max();
string titile = string.Format("{0:yyyyMMdd HHmm} - {1:yyyyMMdd HHmm}", mintm, maxtm);
Bitmap bmp = new Bitmap(Width, Height);
var g = Graphics.FromImage(bmp);
FillBlank(g);
DrawTitle(g, titile);
RectangleF rectbody = new RectangleF((float)(Width * 0.06), (float)(Height * 0.16), (float)(Width * 0.88), (float)(Height * 0.64));
DrawBody(g, rectbody, mintm, maxtm);
RectangleF rectlen = new RectangleF((float)(Width * 0.06), (float)(Height * 0.84), (float)(Width * 0.88), (float)(Height * 0.1));
DrawLegend(g, rectlen);
return bmp;
}
}