Esempio n. 1
0
        private static List <ChartString> CookDashSigns(ChartOptions options, Offsets offsets, List <int> dashesX, List <int> dashesY)
        {
            List <ChartString> result = new List <ChartString>();

            // X dashes' signs
            foreach (int i in dashesX)
            {
                float tx = options.SizeX * (i - options.MinX) / (options.MaxX - options.MinX);
                if (i != 0 && tx - i.ToString().Length *AproximateCharWidth >= 0 &&
                    tx + i.ToString().Length *AproximateCharWidth <= options.SizeX)
                {
                    result.Add(new ChartString {
                        Location = new PointF(tx - i.ToString().Length *AproximateCharWidth, offsets.SignOffsetX), Text = i.ToString()
                    });
                }
            }
            // Y dashes signs
            foreach (int i in dashesY)
            {
                float ty = options.SizeY - options.SizeY * (i - options.MinY) / (options.MaxY - options.MinY);
                if (i != 0 && ty - i.ToString().Length *AproximateCharHigh >= 0 &&
                    ty + i.ToString().Length *AproximateCharHigh <= options.SizeY)
                {
                    result.Add(new ChartString {
                        Location = new PointF(offsets.SignOffsetY, ty - AproximateCharHigh), Text = i.ToString()
                    });
                }
            }
            return(result);
        }
Esempio n. 2
0
        private static List <ChartLine> CookDashLines(ChartOptions options, Offsets offsets, float xAxisLocation, float yAxisLocation, List <int> dashesX, List <int> dashesY)
        {
            List <ChartLine> result = new List <ChartLine>();

            // X axis dashes
            foreach (int i in dashesX)
            {
                float tx = options.SizeX * (i - options.MinX) / (options.MaxX - options.MinX);
                if (xAxisLocation == -1 || tx <= options.SizeX - AxisArrowLength)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(tx, offsets.DashStartX), End = new PointF(tx, offsets.DashEndX)
                    });
                }
            }
            // Y axis dashes
            foreach (int i in dashesY)
            {
                float ty = options.SizeY - options.SizeY * (i - options.MinY) / (options.MaxY - options.MinY);
                if (yAxisLocation == -1 || ty >= AxisArrowLength)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(offsets.DashStartY, ty), End = new PointF(offsets.DashEndY, ty)
                    });
                }
            }
            return(result);
        }
Esempio n. 3
0
        private static Bitmap DrawGrid(List <ChartLine> gridLines, ChartOptions options)
        {
            Bitmap result = new Bitmap(options.SizeX + 1, options.SizeY + 1);

            DrawLines(result, gridLines, GridPen);
            return(result);
        }
Esempio n. 4
0
            public static Offsets Cook(ChartOptions options, float xAxisLocation, float yAxisLocation)
            {
                // X axis elements
                Offsets result = new Offsets();

                if (options.MinY >= 0)
                {
                    result.DashStartX  = options.SizeY - DashLengthHalf;
                    result.DashEndX    = options.SizeY;
                    result.SignOffsetX = options.SizeY - SignOffsetAboveLeft;
                }
                else if (options.MaxY <= 0)
                {
                    result.DashStartX  = 1;
                    result.DashEndX    = DashLengthHalf + 1;
                    result.SignOffsetX = DashLengthHalf + 1;
                }
                else
                {
                    result.DashStartX = (int)Math.Round(xAxisLocation - DashLengthHalf);
                    result.DashEndX   = (int)Math.Round(xAxisLocation + DashLengthHalf);
                    if (Math.Abs(options.MinY) > options.MaxY)
                    {
                        result.SignOffsetX = (int)Math.Round(xAxisLocation) + DashLengthHalf + 1;
                    }
                    else
                    {
                        result.SignOffsetX = (int)Math.Round(xAxisLocation) - SignOffsetAboveLeft;
                    }
                }
                // Y axis elements
                if (options.MinX >= 0)
                {
                    result.DashStartY  = 1;
                    result.DashEndY    = DashLengthHalf + 1;
                    result.SignOffsetY = DashLengthHalf + 1;
                }
                else if (options.MaxX <= 0)
                {
                    result.DashStartY  = options.SizeX - DashLengthHalf;
                    result.DashStartY  = options.SizeX;
                    result.SignOffsetY = options.SizeX - SignOffsetAboveLeft;
                }
                else
                {
                    result.DashStartY = (int)Math.Round(yAxisLocation - DashLengthHalf);
                    result.DashEndY   = (int)Math.Round(yAxisLocation + DashLengthHalf);
                    if (Math.Abs(options.MinX) > options.MaxX)
                    {
                        result.SignOffsetY = (int)Math.Round(yAxisLocation) - SignOffsetAboveLeft;
                    }
                    else
                    {
                        result.SignOffsetY = (int)Math.Round(yAxisLocation) + DashLengthHalf + 1;
                    }
                }
                return(result);
            }
Esempio n. 5
0
        private static List <ChartLine> CookAxisLines(ChartOptions options, out float xAxisLocation, out float yAxisLocation)
        {
            List <ChartLine> result = new List <ChartLine>();

            xAxisLocation = -1;
            yAxisLocation = -1;
            // X Axis and arrow
            if (options.MinY <= 0 && options.MaxY >= 0)
            {
                xAxisLocation = options.SizeY - options.SizeY * (-options.MinY) / (-options.MinY + options.MaxY);
                if (xAxisLocation < 0.5)
                {
                    xAxisLocation = 1;
                }
                result.Add(new ChartLine {
                    Start = new PointF(0, xAxisLocation), End = new PointF(options.SizeX, xAxisLocation)
                });
                if (options.MinY < 0)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(options.SizeX - AxisArrowLength, xAxisLocation + AxisArrowWidth), End = new PointF(options.SizeX, xAxisLocation)
                    });
                }
                if (options.MaxY > 0)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(options.SizeX - AxisArrowLength, xAxisLocation - AxisArrowWidth), End = new PointF(options.SizeX, xAxisLocation)
                    });
                }
            }
            // Y Axis and arrow
            if (options.MinX <= 0 && options.MaxX >= 0)
            {
                yAxisLocation = options.SizeX * (-options.MinX) / (-options.MinX + options.MaxX);
                if (yAxisLocation < 0.5)
                {
                    yAxisLocation = 1;
                }
                result.Add(new ChartLine {
                    Start = new PointF(yAxisLocation, 0), End = new PointF(yAxisLocation, options.SizeY)
                });
                if (options.MinX < 0)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(yAxisLocation - AxisArrowWidth, AxisArrowLength + 1), End = new PointF(yAxisLocation, 1)
                    });
                }
                if (options.MaxX > 0)
                {
                    result.Add(new ChartLine {
                        Start = new PointF(yAxisLocation + AxisArrowWidth, AxisArrowLength + 1), End = new PointF(yAxisLocation, 1)
                    });
                }
            }
            return(result);
        }
Esempio n. 6
0
        private static List <List <PointF> > CalculateChartGraph(ChartOptions chartOptions, MathFunction f)
        {
            List <List <PointF> > allFragments = new List <List <PointF> >();
            List <PointF>         fragment     = new List <PointF>();

            for (int i = 1; i <= chartOptions.SizeX; i++)
            {
                // Cook curve fragments (list of points for every fragment)
                double x = GetRealX(chartOptions, i);
                double y = f(x);
                if (double.IsInfinity(y) || double.IsNaN(y))                 // For example: when processing x asymptote or logarithm of negative value
                {
                    if (fragment.Count > 0)
                    {
                        allFragments.Add(fragment); fragment = new List <PointF>();
                    }
                }
                else
                {
                    float wy = GetRealY(chartOptions, (float)y);
                    if ((float)y > chartOptions.MaxY || (float)y < chartOptions.MinY)
                    {
                        if (fragment.Count > 0)
                        {
                            fragment.Add(new PointF(i, wy));
                            allFragments.Add(fragment);
                            fragment = new List <PointF>();
                        }
                    }
                    else
                    {
                        if (fragment.Count == 0)
                        {
                            fragment.Add(new PointF(i, wy));
                        }
                        else
                        {
                            fragment.Add(new PointF(i, wy));
                        }
                    }
                }
            }
            if (fragment.Count > 0)
            {
                allFragments.Add(fragment);
            }
            return(allFragments);
        }
Esempio n. 7
0
        private static int DetectStep(ChartOptions options)
        {
            int step;

            if ((options.MaxX - options.MinX) > (options.MaxY - options.MinY))
            {
                step = Convert.ToInt32(Math.Round((options.MaxX - options.MinX) / StepDeviderMax));
            }
            else
            {
                step = Convert.ToInt32(Math.Round((options.MaxY - options.MinY) / StepDeviderMax));
            }
            if (step == 0)
            {
                step = 1;
            }
            return(step);
        }
Esempio n. 8
0
        private void Build_Click(object sender, EventArgs e)
        {
            if (Func_box.Text != null)
            {
                Func_box.Text = Func_box.Text.Replace(" ", "");
            }
            if (string.IsNullOrEmpty(Func_box.Text))
            {
                MessageBox.Show("Не задана функция графика"); return;
            }

            // Code generation of math function
            MathFuncCodeGenerator generatedFuncCode = MathFuncCodeGenerator.Generate(Func_box.Text);

            if (string.IsNullOrEmpty(generatedFuncCode.Error))
            {
                FuncCode_box.Text = "Код функции : " + generatedFuncCode.OutputText;
            }
            else
            {
                MessageBox.Show("Ошибка : " + generatedFuncCode.Error); return;
            }

            // Compile (with reflection) method with generated math function
            CompiledMathFunction compiledMathFunction = MathFuncCodeCompiler.CompileMathFuction(generatedFuncCode.OutputText);

            if (!string.IsNullOrWhiteSpace(compiledMathFunction.Error))
            {
                FuncCode_box.Text = $"{FuncCode_box.Text}\nВозникли ошибки компиляции: {compiledMathFunction.Error}";
                return;
            }
            ChartOptions chartOptions =
                AnalyzeChartInputParametersAndCookChartOptions(Xmin_box.Text, Xmax_box.Text, Ymin_box.Text, Ymax_box.Text);

            if (chartOptions.Errors.Count > 0)
            {
                MessageBox.Show("Обнаружны ошибки задания диапазона: " + string.Join("! ", chartOptions.Errors)); return;
            }
            // Create ChartWindow form
            ChartWindow f = new ChartWindow();

            f.InitializeChart(Func_box.Text, chartOptions, compiledMathFunction.Func);
            f.Show();
        }
 public void InitializeChart(string mathFuncText, ChartOptions chartParametrs, MathFunction mathFunc)
 {
     FunctionLabel.Text = "y=" + mathFuncText;
     // Adjusting of window and chart area
     Size            = new Size(chartParametrs.SizeX + 23, chartParametrs.SizeY + 66);
     FormBorderStyle = FormBorderStyle.FixedSingle;
     Chart.Size      = new Size(chartParametrs.SizeX + 1, chartParametrs.SizeY + 1);
     Chart.Location  = new Point(3, 23);
     Chart.Visible   = true;
     // Initialization and drawing of chart images
     Images = new ChartWindowGraphics(chartParametrs);
     Images.CookBitmaps();
     Images.AddChartImage(ChartImageGraphics.GetChartImage(chartParametrs, mathFunc));
     // Initialization and adjusting of axis/grid options' checks
     GridOption.Location = new Point(chartParametrs.SizeX - 100, 3);
     AxisOption.Location = new Point(chartParametrs.SizeX - 40, 3);
     AxisOption.Checked  = true;
     GridOption.Checked  = false;
 }
Esempio n. 10
0
        private static Bitmap DrawImage(ChartOptions chartOptions, List <List <PointF> > allFragments)
        {
            Bitmap   image = new Bitmap(chartOptions.SizeX + 1, chartOptions.SizeY + 1);
            Graphics g     = Graphics.FromImage(image);

            using (g)
            {
                g.Clear(Color.White);
                Pen p = new Pen(Color.Blue, 2);
                p.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
                foreach (List <PointF> onef in allFragments)
                {
                    if (onef.Count == 1)
                    {
                        onef.Add(onef[0]);
                    }                                                               // If fragment contains only 1 point - add the same second point in order to draw line
                    g.DrawCurve(p, onef.ToArray());
                }
            }
            return(image);
        }
Esempio n. 11
0
        private static List <ChartLine> CookGridLines(ChartOptions options, List <int> dashesX, List <int> dashesY)
        {
            List <ChartLine> result = new List <ChartLine>();

            // Y parallels
            foreach (int i in dashesX)
            {
                float tx = options.SizeX * (i - options.MinX) / (options.MaxX - options.MinX);
                result.Add(new ChartLine {
                    Start = new PointF(tx, 0), End = new PointF(tx, options.SizeY + 1)
                });
            }
            // X parallels
            foreach (int i in dashesY)
            {
                float ty = options.SizeY - options.SizeY * (i - options.MinY) / (options.MaxY - options.MinY);
                result.Add(new ChartLine {
                    Start = new PointF(0, ty), End = new PointF(options.SizeX + 1, ty)
                });
            }
            return(result);
        }
Esempio n. 12
0
 public ChartWindowGraphics(ChartOptions options)
 {
     Options = options;
 }
Esempio n. 13
0
        public static ChartOptions AnalyzeChartInputParametersAndCookChartOptions(
            string minX, string maxX, string minY, string maxY)
        {
            ChartOptions chartOptions = new ChartOptions();

            chartOptions.Errors = new List <string>();
            if (!float.TryParse(minX, out chartOptions.MinX))
            {
                chartOptions.Errors.Add("Нечисловое значение в поле дипазона \"min X\"");
            }
            if (!float.TryParse(maxX, out chartOptions.MaxX))
            {
                chartOptions.Errors.Add("Нечисловое значение в поле дипазона \"max X\"");
            }
            if (!float.TryParse(minY, out chartOptions.MinY))
            {
                chartOptions.Errors.Add("Нечисловое значение в поле дипазона \"min Y\"");
            }
            if (!float.TryParse(maxY, out chartOptions.MaxY))
            {
                chartOptions.Errors.Add("Нечисловое значение в поле дипазона \"max Y\"");
            }
            if (chartOptions.Errors.Count != 0)
            {
                return(chartOptions);
            }
            if (chartOptions.MinX > 1000 || chartOptions.MinX < -1000)
            {
                chartOptions.Errors.Add("Значение в поле \"min X\" находится за пределами допустимого диапазона [-1000..1000]");
            }
            if (chartOptions.MaxX > 1000 || chartOptions.MaxX < -1000)
            {
                chartOptions.Errors.Add("Значение в поле \"max X\" находится за пределами допустимого диапазона [-1000..1000]");
            }
            if (chartOptions.MinY > 1000 || chartOptions.MinY < -1000)
            {
                chartOptions.Errors.Add("Значение в поле \"min Y\" находится за пределами допустимого диапазона [-1000..1000]");
            }
            if (chartOptions.MaxY > 1000 || chartOptions.MaxY < -1000)
            {
                chartOptions.Errors.Add("Значение в поле \"max Y\" находится за пределами допустимого диапазона [-1000..1000]");
            }
            if (chartOptions.MinX == chartOptions.MaxX)
            {
                chartOptions.Errors.Add("\"min X\" и \"max X\" не могут быть равными");
            }
            if (chartOptions.MinY == chartOptions.MaxY)
            {
                chartOptions.Errors.Add("\"min Y\" и \"max Y\" не могут быть равными");
            }
            if (chartOptions.Errors.Count != 0)
            {
                return(chartOptions);
            }
            if (chartOptions.MinX > chartOptions.MaxX)
            {
                SwapFloats(ref chartOptions.MinX, ref chartOptions.MaxX);
            }
            if (chartOptions.MinY > chartOptions.MaxY)
            {
                SwapFloats(ref chartOptions.MinY, ref chartOptions.MaxY);
            }
            double lx  = chartOptions.MaxX - chartOptions.MinX;
            double ly  = chartOptions.MaxY - chartOptions.MinY;
            double dxy = lx / ly;

            if (dxy < 50.0 / 800 || dxy > 800 / 50.0)
            {
                chartOptions.Errors.Add("Соотношение диапазонов вывода не может быть больше 16");
                return(chartOptions);
            }
            if (lx > ly)
            {
                chartOptions.SizeX = 800; chartOptions.SizeY = (int)Math.Round(800 * ly / lx);
            }
            else
            {
                chartOptions.SizeY = 800; chartOptions.SizeX = (int)Math.Round(800 * lx / ly);
            }
            return(chartOptions);
        }
Esempio n. 14
0
 private static float GetRealY(ChartOptions me, float y)
 {
     return((me.MaxY - y) * me.SizeY / (me.MaxY - me.MinY));
 }
Esempio n. 15
0
 private static float GetRealX(ChartOptions me, int x)
 {
     return(me.MinX + (me.MaxX - me.MinX) * x / me.SizeX);
 }
Esempio n. 16
0
        public static Bitmap GetChartImage(ChartOptions chartOptions, MathFunction f)
        {
            List <List <PointF> > allFragments = CalculateChartGraph(chartOptions, f);

            return(DrawImage(chartOptions, allFragments));
        }