using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Chart
{
public class SimpleCoordinator : ICoordPainter
{
private double[] sc = { 0.01, 0.02, 0.05, .1, .2, .5, 1.0, 2.0, 5.0, 10, 20, 50 };
protected int[] n = new int[2];
protected double[] scale = new double[2];
protected int[] p = new int[2];
protected ChartPerformer performer;
public SimpleCoordinator(int nx, int ny, ChartPerformer performer)
{
this.performer = performer;
n[0] = nx;
n[1] = ny;
}
public static void ClearInsetsStatic(Control component, int[,] insets)
{
if (component == null)
{
return;
}
Color c = component.BackColor;
Graphics g = Graphics.FromHwnd(component.Handle);
Brush brush = new SolidBrush(c);
g.FillRectangle(brush, 0, 0, insets[0, 0] - 1, component.Height);
g.FillRectangle(brush, 0, component.Height - insets[1, 1] + 1, component.Width,
insets[1, 1] - 1);
}
public virtual void ClearInsets(Control component, int[,] insets)
{
ClearInsetsStatic(component, insets);
}
public virtual void DrawCoord(Graphics g, double[,] dSize, int[] size)
{
calculateScale(dSize);
DrawCoord(g, size, dSize, 0);
DrawCoord(g, size, dSize, 1);
}
public virtual void DrawCoord(Graphics g, int[,] insets, double[,] dSize, int[] size)
{
calculateScale(dSize);
Pen pen = new Pen(Color.Black);
g.DrawRectangle(pen, insets[0, 0] - 1, insets[0, 1] - 1, size[0] + 2, size[1] + 2);
drawTextX(g, insets, dSize, size);
drawTextY(g, insets, dSize, size);
}
protected void calculateScale(double[,] dSize, int i)
{
double a = (dSize[1, i] - dSize[0, i]) / n[i];
double log = Math.Log(a) / Math.Log(10.0);
int lg = (int)Math.Ceiling(log);
double c = 1;
if (lg > 0)
{
for (int j = 0; j < lg; j++)
{
c *= 10;
}
}
else
{
for (int j = 0; j > lg; j--)
{
c /= 10;
}
}
double ss = c * sc[0];
double acc = Math.Abs(ss - a);
for (int j = 1; j < sc.Length; j++)
{
double sss = c * sc[j];
double d = Math.Abs(sss - a);
if (d < acc)
{
ss = sss;
acc = d;
}
}
scale[i] = ss;
}
protected void calculateScale(double[,] dSize)
{
calculateScale(dSize, 0);
calculateScale(dSize, 1);
}
protected void DrawCoord(Graphics g, int[] size, double[,] dSize, int i)
{
double sc = scale[i];
if (sc == 0)
{
return;
}
double a = dSize[0, i] / sc;
long k = (long)a - 1;
double c = k * sc;
Pen pen = new Pen(Color.Black);
while (c < dSize[1, i])
{
if (c > dSize[0, i])
{
if (i == 0)
{
performer.Transform(c, 0.0, p);
g.DrawLine(pen, p[0], 0, p[0], size[1]);
}
else
{
performer.Transform(0, c, p);
g.DrawLine(pen, 0, p[1], size[0], p[1]);
}
}
c += sc;
}
}
protected void drawTextX(Graphics g, int[,] insets, double[,] dSize, int[] size)
{
double sc = scale[0];
if (sc == 0)
{
return;
}
int k = (int)(dSize[0, 0] / sc) - 1;
double c = k * sc;
Font font = new Font("Times", 13);
Brush brush = new SolidBrush(Color.Black);
int h = font.Height + insets[0, 1] + size[1];
while (c < dSize[1, 0])
{
if (c > dSize[0, 0])
{
performer.Transform(c, 0.0, p);
string s = transformString(c, sc);
int w = (int)g.MeasureString(s, font).Width;
g.DrawString(s, font, brush, p[0] + insets[0, 0] - w / 2, h);
}
c += sc;
}
}
protected void drawTextY(Graphics g, int[,] insets, double[,] dSize, int[] size)
{
double sc = scale[1];
if (sc == 0)
{
return;
}
long k = (long)(dSize[0, 1] / sc) - 1;
double c = k * sc;
Brush brush = new SolidBrush(Color.Black);
Font font = new Font("Times", 13);
while (c < dSize[1, 1])
{
if (c > dSize[0, 1])
{
performer.Transform(0.0, c, p);
string s = transformString(c, sc);
int w = (int)g.MeasureString(s, font).Width;
g.DrawString(s, font, brush, insets[0, 0] - (int)(double)(1.2 * w), p[1] + insets[0, 1]);
}
c += sc;
}
}
private string transformString(double d, double sc)
{
Double a = d;
String s = a.ToString();
while (true)
{
if (s.Length > 3 & s.IndexOf('E') < 0 & s.IndexOf('e') < 0)
{
String s1 = s.Substring(0, s.Length - 1);
double d1 = Double.Parse(s1);
if (Math.Abs(d - d1) < 0.5 * sc)
{
s = s1;
}
else
{
break;
}
}
else
{
break;
}
}
return s;
}
}
}