XY GRAFIK
XY Graphics
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

    }
}





XY Graphics

Graphic Projekte

Projekte

Ableitungen:
Ableitungen.zip

La Grange: LaGrange.zip

Test Graphic: TestXYGraphics.zip



Beispiel Grafiken

















Tree
MS Office