|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Globalization;
namespace TestXYGraphics {
public class XYGraphic : Control {
private int nr = 0;
private Gitter gitter = new Gitter();
private Achse xAchse = new Achse();
private Achse yAchse = new Achse();
private Graphic graphic = null;
private FormattedText formattedText;
private double fontHeight = 0.0;
private List<PointXY> coords = null;
private Pen penBlack = new Pen(Brushes.Black, 1);
public XYGraphic() {
graphic = new Graphic(gitter, xAchse, yAchse);
Color brushText = Colors.Black;
formattedText = new FormattedText("888.88", CultureInfo.GetCultureInfo("DE-de"), FlowDirection.LeftToRight,
new Typeface("Verdana"), 11, new SolidColorBrush(brushText)); // text.brushText));
fontHeight = formattedText.Height;
graphic.setFormattedText(this.formattedText);
}
public void setGraphic(String title, String xname, String yname, double xa, double xsw, double xe, double ya, double ysw, double ye) {
this.gitter.title = title;
this.xAchse.bezeichnung = xname;
this.yAchse.bezeichnung = yname;
this.xAchse.xa = xa;
this.xAchse.xsw = xsw;
this.xAchse.xe = xe;
this.xAchse.setNachkommastellen();
this.yAchse.xa = ya;
this.yAchse.xsw = ysw;
this.yAchse.xe = ye;
this.yAchse.setNachkommastellen();
// this.f = new Font("Verdana", Font.PLAIN, 14);
coords = null; // muss erst gesetzt werden
graphic.coords = null;
this.InvalidateVisual();
}
public void setCoords(List<PointXY> coords) {
this.coords = coords;
graphic.coords = coords;
this.InvalidateVisual();
} // setCoords
protected override void OnRender(DrawingContext dc) {
base.OnRender(dc);
double width = this.ActualWidth;
double height = this.ActualHeight;
// dc.DrawLine(penBlack, new Point(10, 10), new Point(100, 200));
bool b1 = this.ActualWidth > 0;
bool b2 = this.ActualHeight > 0;
if (!b1 || !b1) return;
gitter.pixY0 = fontHeight + fontHeight + fontHeight; // Ziffern Xname
gitter.pixHeight = this.ActualHeight - gitter.pixY0 - (fontHeight + fontHeight);
gitter.pixX0 = formattedText.Width;
gitter.pixWidth = this.ActualWidth - gitter.pixX0 - gitter.pixX0;
gitter.MaxY = this.ActualHeight; // y inverted
gitter.MaxX = this.ActualWidth;
gitter.pixTop = gitter.pixY0 + gitter.pixHeight; // obere Rahmenhoehe
graphic.setFactors();
// penBlack.DashStyle = DashStyles.Dash;
Rect rect = new Rect(0, 0, Width, Height);
dc.DrawRectangle(Brushes.Green, penBlack, rect);
graphic.drawGitter(dc);
graphic.drawCoords(dc);
}
public override String ToString() {
StringBuilder sb = new StringBuilder();
sb.AppendLine("Xa: " + 0.0);
sb.AppendLine("Xsw: " + 1.0);
sb.AppendLine("Xe: " + 10.0);
sb.AppendLine("Ya: " + 0.0);
sb.AppendLine("Ysw: " + 1.0);
sb.AppendLine("Ye: " + 10.0);
if (coords != null) {
PointXY p;
for (int i = 0; i < coords.Count; i++) {
p = coords[i];
sb.AppendLine("x[" + i + "] = " + p.x);
sb.AppendLine("y[" + i + "] = " + p.y);
}
}
return sb.ToString();
}
// -----------------------
class Graphic {
public FormattedText formattedText=null;
public double fontheight = 0.0;
public Gitter gitter = null;
public Achse xAchse = null;
public Achse yAchse = null;
private double faktorGowXPlus = 0.0;
private double faktorGowXMinus = 0.0;
private double faktorGowYPlus = 0.0;
private double faktorGowYMinus = 0.0;
public List<PointXY> coords = null;
private Pen penBlack = new Pen(Brushes.Black, 1);
private Pen penBlue = new Pen(Brushes.Blue, 2);
private Point p1 = new Point();
private Point p2 = new Point();
public Graphic(Gitter gitter, Achse xAchse, Achse yAchse) {
this.gitter = gitter;
this.xAchse = xAchse;
this.yAchse = yAchse;
}
public void setFormattedText(FormattedText formattedText) {
this.formattedText = formattedText;
this.fontheight = formattedText.Height;
}
public void setFactors() {
this.faktorGowXPlus = gitter.pixWidth / (xAchse.xe - xAchse.xa);
this.faktorGowXMinus = gitter.pixWidth / (xAchse.xa - xAchse.xe);
this.faktorGowYPlus = gitter.pixHeight / (yAchse.xe - yAchse.xa);
this.faktorGowYMinus = gitter.pixHeight / (yAchse.xa - yAchse.xe);
}
internal void drawGitter(DrawingContext dc) {
Rect rect = new Rect(gitter.pixX0, gitter.MaxY - gitter.pixTop, gitter.pixWidth, gitter.pixHeight);
dc.DrawRectangle(null, penBlack, rect);
if (xAchse.xa < xAchse.xe) {
if (xAchse.xsw < 0.0) xAchse.xsw = Math.Abs(xAchse.xsw);
}
else {
if (xAchse.xsw > 0.0) xAchse.xsw = -xAchse.xsw;
}
if (xAchse.xsw > 0)
drawXLinesPlus(dc);
else
drawXLinesMinus(dc);
drawYLines(dc);
drawTextZentr(dc,14, gitter.pixX0 + (gitter.pixWidth * 0.5), 20, gitter.title);
drawTextZentr(dc,11, gitter.pixX0 + (gitter.pixWidth * 0.5), gitter.MaxY - (gitter.pixY0 - fontheight - fontheight - 4), xAchse.bezeichnung);
drawTextZentrY(dc, 20, gitter.MaxY - (gitter.pixY0 - gitter.pixHeight * 0.5 - 4), yAchse.bezeichnung);
// drawTextZentrY(dc, 220, gitter.MaxY - (gitter.pixY0 - gitter.pixHeight * 0.5 - 4), yAchse.bezeichnung);
}
internal void drawXLinesPlus(DrawingContext dc) {
/* xee=ende da Rundungsfehler auftreten k÷nnen */
int i = 0;
int xlen = 5;
double pos, ix;
bool erster = true;
bool letzter = false;
double x = xAchse.xa;
double xee = xAchse.xe + xAchse.xsw * 0.01;
double ymin = gitter.MaxY - (gitter.pixY0 - xlen);
double ymax = gitter.MaxY - (gitter.pixTop);
double yfont = gitter.MaxY - (gitter.pixY0 - xlen - fontheight);
while (x <= xee) {
i++;
pos = GOWandleX(x);
ix = gitter.pixX0 + pos;
letzter = (x + xAchse.xsw) > xee;
if (erster) {
p1.X = gitter.pixX0;
p1.Y = ymin;
p2.X = gitter.pixX0;
p2.Y = gitter.pixY0;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, gitter.pixX0, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
else if (letzter) {
p1.X = gitter.pixX0 + gitter.pixWidth;
p1.Y = ymin;
p2.X = gitter.pixX0 + gitter.pixWidth;
p2.Y = gitter.pixY0;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, gitter.pixX0 + gitter.pixWidth, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
else {
p1.X = ix;
p1.Y = ymin;
p2.X = ix;
p2.Y = ymax;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, ix, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
x += xAchse.xsw;
erster = false;
}
} // drawXLinesPlus
internal void drawXLinesMinus(DrawingContext dc) {
/* xee=ende da Rundungsfehler auftreten k÷nnen */
int i = 0;
int xlen = 5;
double pos, ix;
bool erster = true;
bool letzter = false;
double x = xAchse.xa; // xa > xe
double xee = xAchse.xe + xAchse.xsw * 0.01;
double ymin = gitter.MaxY - (gitter.pixY0 - xlen);
double ymax = gitter.MaxY - (gitter.pixTop);
double yfont = gitter.MaxY - (gitter.pixY0 - xlen - fontheight);
while (x >= xee) {
i++;
pos = GOWandleX(x);
ix = gitter.pixX0 + pos;
letzter = (x + xAchse.xsw) < xee;
if (erster) {
p1.X = gitter.pixX0;
p1.Y = ymin;
p2.X = gitter.pixX0;
p2.Y = gitter.pixY0;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, gitter.pixX0, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
else if (letzter) {
p1.X = gitter.pixX0 + gitter.pixWidth;
p1.Y = ymin;
p2.X = gitter.pixX0 + gitter.pixWidth;
p2.Y = gitter.pixY0;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, gitter.pixX0 + gitter.pixWidth, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
else {
p1.X = ix;
p1.Y = ymin;
p2.X = ix;
p2.Y = ymax;
dc.DrawLine(penBlack, p1, p2);
drawTextZentr(dc, 11, ix, yfont, getNumberWithFormat(x, xAchse.nachkommastellen));
}
x += xAchse.xsw;
erster = false;
}
}
private String getNumberWithFormat(double x, int nachkommastellen) {
switch (nachkommastellen) {
case 0: return x.ToString("0");
case 1: return x.ToString("0.0");
case 2: return x.ToString("0.00");
case 3: return x.ToString("0.000");
case 4: return x.ToString("0.0000");
case 5: return x.ToString("0.00000");
default: return x.ToString("0.00000");
}
}
private void drawTextZentr(DrawingContext dc, int fontsize, double x, double y, String value) {
if (value.Length == 0) {
return;
}
else {
FormattedText formattedText = new FormattedText(value, CultureInfo.GetCultureInfo("DE-de"),
FlowDirection.LeftToRight, new Typeface("Verdana"), fontsize, new SolidColorBrush(Colors.Black));
double wx = formattedText.Width;
dc.DrawText(formattedText, new Point(x - (wx * 0.5), y - fontheight));
}
} // drawTextZentr
private void drawTextZentrY(DrawingContext dc, double x, double y, String value) {
if (value.Length == 0) {
return;
}
else {
FormattedText formattedText = new FormattedText(value, CultureInfo.GetCultureInfo("DE-de"),
FlowDirection.LeftToRight, new Typeface("Verdana"), 11, new SolidColorBrush(Colors.Black));
double wx = formattedText.Width*0.5;
double gx = -wx - gitter.MaxY*0.5; // +wx;
double gy = 5; // gitter.MaxX - y;
RotateTransform RT = new RotateTransform(270, 0, 0);
dc.PushTransform(RT);
dc.DrawText(formattedText, new Point(gx,gy));
//dc.DrawLine(penBlack, new Point(0, 0), new Point(-100, -100));
//dc.DrawLine(penBlack, new Point(0, 0), new Point(-100, 100));
dc.Pop();
}
} // drawTextZentrY
private void drawTextRight(DrawingContext dc, double x, double y, String value) {
if (value.Length == 0) {
return;
}
else {
FormattedText formattedText = new FormattedText(value, CultureInfo.GetCultureInfo("DE-de"),
FlowDirection.LeftToRight, new Typeface("Verdana"), 11, new SolidColorBrush(Colors.Black));
double wx = formattedText.Width;
dc.DrawText(formattedText, new Point(x-wx, y ));
}
} // drawTextLeft
internal void drawYLines(DrawingContext dc) {
int i = 0;
double ylen = 5;
double pos, iy, iyy;
bool erster = true;
bool letzter = false;
double y = yAchse.xa;
double yee = yAchse.xe + yAchse.xsw * 0.01;
double xmin = gitter.pixX0 - ylen;
double xmax = gitter.pixX0 + gitter.pixWidth;
double xfont = gitter.pixX0 - ylen-3; // fontheight; // -ylen
double fonthalbe = fontheight *0.5;
while (y <= yee) {
i++;
pos = GOWandleY(y);
iy = gitter.MaxY - (gitter.pixY0 + pos);
letzter = (y + yAchse.xsw) > yee;
if (erster) {
iyy = gitter.MaxY - gitter.pixY0;
p1.X = gitter.pixX0 - ylen;
p1.Y = iyy;
p2.X = gitter.pixX0;
p2.Y = iyy;
dc.DrawLine(penBlack, p1, p2);
}
else if (letzter) {
iyy = gitter.MaxY - (gitter.pixY0 + gitter.pixHeight);
p1.X = gitter.pixX0 - ylen;
p1.Y = iyy;
p2.X = gitter.pixX0;
p2.Y = iyy;
dc.DrawLine(penBlack, p1, p2);
}
else {
p1.X = xmin;
p1.Y = iy;
p2.X = xmax;
p2.Y = iy;
dc.DrawLine(penBlack, p1, p2);
}
drawTextRight(dc, xfont, iy - fonthalbe, getNumberWithFormat(y, yAchse.nachkommastellen));
y += yAchse.xsw;
erster = false;
}
}
internal void drawCoords(DrawingContext dc) {
if (coords == null) return;
int n = coords.Count;
double ix1, iy1, ix2, iy2;
PointXY cp1, cp2;
for (int i = 0; i < n - 1; i++) {
cp1 = coords[i];
cp2 = coords[i+1];
ix1 = gitter.pixX0 + GOWandleX(cp1.x);
iy1 = gitter.pixY0 + GOWandleY(cp1.y);
ix2 = gitter.pixX0 + GOWandleX(cp2.x);
iy2 = gitter.pixY0 + GOWandleY(cp2.y);
p1.X = ix1;
p1.Y = gitter.MaxY - iy1;
p2.X = ix2;
p2.Y = gitter.MaxY - iy2;
dc.DrawLine( penBlue, p1, p2);
}
}
private double GOWandleX(double x) {
double r, d1, result;
result = 0;
if (xAchse.xsw > 0) {
d1 = faktorGowXPlus * (x - xAchse.xa);
if (d1 < 0) d1 = 0;
result = d1;
}
else {
d1 = faktorGowXMinus * (xAchse.xa - x);
if (d1 < 0) d1 = 0;
result = d1;
}
return (int)result;
} // GOWandlex
private double GOWandleY(double y) {
double r, d1, result;
result = 0;
if (yAchse.xsw > 0) {
d1 = faktorGowYPlus * (y - yAchse.xa);
if (d1 < 0) d1 = 0;
result = d1;
}
else {
r = faktorGowYMinus * (yAchse.xa - y);
d1 = r + gitter.pixY0;
if (d1 < 0) d1 = 0;
result = d1;
}
return (int)result;
} // GOWandley
} // Graphic
class Gitter {
public double MaxY = 0;
public double MaxX = 0;
public double pixWidth = 0;
public double pixHeight = 0;
public double pixX0; // Koordinatenursprung
public double pixY0;
public double pixTop; // gitter.pixY0-gitter.pixHeight
public String title="";
}
public class PointXY {
public double x=0;
public double y=0;
public PointXY(double x, double y) {
this.x = x;
this.y = y;
}
}
class Achse {
public double xa;
public double xsw;
public double xe;
public int nachkommastellen;
public int ticks;
public String bezeichnung = "";
public Achse() {
xa = 0.0;
xsw = 1;
xe = 10;
nachkommastellen = 0;
ticks = 4;
}
public void setNachkommastellen() {
int nk = -1;
double dummy;
String str;
String format="0.";
for (int i = 0; i < 5; i++) {
str = xsw.ToString(format);
dummy = Double.Parse(str);
if (xsw == dummy) {
nk = i;
break;
}
format += "0";
}
if (nk == -1)
nachkommastellen = 5;
else
nachkommastellen = nk;
}
} // Achse
}
}
|
|