Пример #1
0
 /// <summary>
 /// Reset zoom on all plot axes.
 /// </summary>
 /// <param name="sender">Not used.</param>
 /// <param name="e">Not used.</param>
 private void ButtonResetZoom_Click(object sender, RoutedEventArgs e)
 {
     PlotView.ResetAllAxes();
 }
Пример #2
0
        public MainWindow() : base(new[]
        {
            "resm:OxyPlot.Avalonia.Themes.Default.xaml?assembly=OxyPlot.Avalonia"
        })
        {
            var grRoot = new Grid()
            {
                DataContext = m, Margin = new Thickness(10)
            };

            grRoot.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Auto));
            grRoot.RowDefinitions.Add(new RowDefinition(1, GridUnitType.Star));
            grRoot.RowDefinitions.Add(new RowDefinition(100, GridUnitType.Pixel));

            pv       = new PlotView();
            pv.Model = new PlotModel();
            Grid.SetRow(pv, 1);
            grRoot.Children.Add(pv);

            var grSplit = new GridSplitter()
            {
                Height = 10, VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top
            };

            Grid.SetRow(grSplit, 2);
            grRoot.Children.Add(grSplit);

            tboxLog = new TextBox()
            {
                Margin = new Thickness(0, 20, 0, 0)
            };
            Grid.SetRow(tboxLog, 2);
            grRoot.Children.Add(tboxLog);

            var durationConverter        = new QuantityConverter((s, c) => Duration.Parse(s, c));
            var rotationalSpeedConverter = new QuantityConverter((s, c) => RotationalSpeed.Parse(s, c));

            {
                var sp = new StackPanel()
                {
                    Orientation = Avalonia.Layout.Orientation.Vertical
                };

                Func <string, TextBlock> tblkField = (s) =>
                                                     new TextBlock
                {
                    Text = s,
                    VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
                    FontWeight        = FontWeight.Bold,
                    Margin            = new Thickness(10, 0, 0, 0)
                };

                Func <string, IValueConverter, TextBox> tboxField = (propname, cvt) =>
                {
                    var tbox = new TextBox {
                        MinWidth = 100, Margin = new Thickness(10, 0, 0, 0)
                    };
                    tbox[!TextBox.TextProperty] = new Binding(propname)
                    {
                        Mode = BindingMode.TwoWay, Converter = cvt
                    };
                    return(tbox);
                };


                {
                    var spH = new StackPanel()
                    {
                        Orientation = Avalonia.Layout.Orientation.Horizontal
                    };
                    sp.Children.Add(spH);

                    TextBox durationTbox = null;
                    spH.Children.Add(tblkField("Duration").Eval((tblk) => { tblk.Margin = new Thickness(); return(tblk); }));
                    spH.Children.Add(durationTbox = tboxField("Duration", durationConverter));

                    var sld = new Slider()
                    {
                        Width       = 200,
                        Minimum     = 0.5,
                        Maximum     = 10,
                        LargeChange = 0.5,
                        SmallChange = 0.5,
                        Value       = m.Duration.Seconds
                    };
                    sld.PropertyChanged += (a, b) =>
                    {
                        if (b.Property.Name == "Value")
                        {
                            var prev = m.Duration.Seconds;
                            var next = sld.Value.MRound(0.5);
                            if (prev != next)
                            {
                                m.Duration        = Duration.FromSeconds(next);
                                durationTbox.Text = m.Duration.ToString();
                                Recompute();
                            }
                        }
                    };
                    spH.Children.Add(sld);

                    spH.Children.Add(tblkField("TargetSpeed"));
                    spH.Children.Add(tboxField("TargetSpeed", rotationalSpeedConverter));

                    spH.Children.Add(tblkField("RenderPts"));
                    spH.Children.Add(tboxField("RenderPts", null));
                }

                {
                    sp.Children.Add(new TextBlock()
                    {
                        Text   = "plot mouse LEFT:(show value) - WHEEL:(zoom 1clk=rect-zoom 2clk=fit) - RIGHT:pan",
                        Margin = new Thickness(0, 10, 0, 0)
                    });
                }

                var btnRefresh = new Button()
                {
                    Content = "Refresh"
                };
                btnRefresh.Click += (a, b) =>
                {
                    Recompute();
                };
                sp.Children.Add(btnRefresh);

                Grid.SetRow(sp, 0);
                grRoot.Children.Add(sp);
            }

            {
                Recompute();
                pv.ResetAllAxes();
                pv.InvalidatePlot();
            }

            this.Content = grRoot;
        }
Пример #3
0
        void Recompute()
        {
            pv.Model.Series.Clear();

            var sb = new StringBuilder();

            var accelBase         = "1-cos(t)";
            var accelOverDuration = accelBase.Substitute("t", $"(t/(d/2)*2*pi)");
            var accelCoeff        = $"s / abs({accelOverDuration.Integrate("t").Substitute("t", "(d/2)")})";
            var accel             = $"({accelCoeff}) * ({accelOverDuration})";
            var accelInt          = accel.Integrate("t");
            var speed             = accelInt;
            var speedAtHalf       = accelInt.Substitute("t", "(d/2)");
            var speedInt          = speed.Integrate("t");
            var posAtZero         = speedInt.Substitute("t", 0);
            var pos       = $"({speedInt})-{(posAtZero)}";
            var posAtHalf = pos.Substitute("t", "(d/2)");

            var targetspeed = $"{pos.ToString()}=x".Substitute("t", "d/2").Solve("s");

            var deAccelBase         = "cos(t)-1";
            var deAccelOverDuration = deAccelBase.Substitute("t", $"(t/(d/2)*2*pi)");
            var deAccelCoeff        = $"s / abs({deAccelOverDuration.Integrate("t").Substitute("t", "(d/2)")})";
            var deAccel             = $"({deAccelCoeff})*({deAccelOverDuration})";
            var deAccelInt          = deAccel.Integrate("t");
            var deSpeedAtZero       = deAccelInt.Substitute("t", 0);
            var deSpeedAtHalf       = deAccelInt.Substitute("t", "(d/2)");
            var deSpeed             = $"({deAccelInt})-({deSpeedAtZero})+({speedAtHalf})";
            var deSpeedInt          = deSpeed.Integrate("t");
            var dePosAtZero         = deSpeedInt.Substitute("t", 0);
            var dePos = $"({deSpeedInt})-({dePosAtZero})+({posAtHalf})";

            var t      = Duration.FromSeconds(0);
            var t_step = m.Duration / m.RenderPts;

            var accelDataSet = new List <PlotData>();
            var speedDataSet = new List <PlotData>();
            var posDataSet   = new List <PlotData>();

            var deAccelDataSet = new List <PlotData>();
            var deSpeedDataSet = new List <PlotData>();
            var dePosDataSet   = new List <PlotData>();

            var accelCompiled = accel
                                .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                                .Substitute("d", m.Duration.Seconds)
                                .Compile("t");

            var deAccelCompiled = deAccel
                                  .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                                  .Substitute("d", m.Duration.Seconds)
                                  .Compile("t");

            var speedCompiled = speed
                                .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                                .Substitute("d", m.Duration.Seconds)
                                .Compile("t");

            var deSpeedCompiled = deSpeed
                                  .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                                  .Substitute("d", m.Duration.Seconds)
                                  .Compile("t");

            var posCompiled = pos
                              .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                              .Substitute("d", m.Duration.Seconds)
                              .Compile("t");

            var dePosCompiled = dePos
                                .Substitute("s", m.TargetSpeed.RevolutionsPerSecond)
                                .Substitute("d", m.Duration.Seconds)
                                .Compile("t");

            var halfDuration = m.Duration / 2;

            var timeTol = Duration.FromNanoseconds(1);

            while (t.LessThanOrEqualsTol(timeTol, m.Duration))
            {
                if (t.LessThanOrEqualsTol(timeTol, halfDuration))
                {
                    accelDataSet.Add(new PlotData(
                                         t.Seconds,
                                         double.Parse(accelCompiled.Substitute(t.Seconds).Real.ToString())));

                    speedDataSet.Add(new PlotData(
                                         t.Seconds,
                                         double.Parse(speedCompiled.Substitute(t.Seconds).Real.ToString())));

                    posDataSet.Add(new PlotData(
                                       t.Seconds,
                                       double.Parse(posCompiled.Substitute(t.Seconds).Real.ToString())));
                }

                if (t.GreatThanOrEqualsTol(timeTol, halfDuration))
                {
                    deAccelDataSet.Add(new PlotData(
                                           t.Seconds,
                                           double.Parse(deAccelCompiled.Substitute((t - halfDuration).Seconds).Real.ToString())));

                    deSpeedDataSet.Add(new PlotData(
                                           t.Seconds,
                                           double.Parse(deSpeedCompiled.Substitute((t - halfDuration).Seconds).Real.ToString())));

                    dePosDataSet.Add(new PlotData(
                                         t.Seconds,
                                         double.Parse(dePosCompiled.Substitute((t - halfDuration).Seconds).Real.ToString())));
                }

                t += t_step;
            }

            var accelSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "Accel (rps2)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = accelDataSet,
                Color       = OxyColor.Parse("#9ccc65")
            };

            pv.Model.Series.Add(accelSerie);

            var deAccelSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "DeAccel (rps2)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = deAccelDataSet,
                Color       = OxyColor.Parse("#6b9b37")
            };

            pv.Model.Series.Add(deAccelSerie);

            var speedSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "Speed (rps)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = speedDataSet,
                Color       = OxyColor.Parse("#42a5f5")
            };

            pv.Model.Series.Add(speedSerie);

            var deSpeedSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "DeSpeed (rps)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = deSpeedDataSet,
                Color       = OxyColor.Parse("#0077c2")
            };

            pv.Model.Series.Add(deSpeedSerie);

            var posSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "Pos (rev)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = posDataSet,
                Color       = OxyColor.Parse("#ef5350")
            };

            pv.Model.Series.Add(posSerie);

            var dePosSerie = new OxyPlot.Series.LineSeries()
            {
                Title       = "DePos (rev)",
                DataFieldX  = "x",
                DataFieldY  = "y",
                ItemsSource = dePosDataSet,
                Color       = OxyColor.Parse("#b61827")
            };

            pv.Model.Series.Add(dePosSerie);

            pv.Model.Annotations.Clear();
            var note = new OxyPlot.Annotations.ArrowAnnotation
            {
                StartPoint = new DataPoint(m.Duration.Seconds / 2, m.TargetSpeed.RevolutionsPerSecond * 1.3),
                EndPoint   = new DataPoint(m.Duration.Seconds / 2, m.TargetSpeed.RevolutionsPerSecond),
                Text       = "targetspeed"
            };

            pv.Model.Annotations.Add(note);

            pv.ResetAllAxes();
            foreach (var x in pv.Model.Axes)
            {
                x.MajorGridlineStyle = LineStyle.Dot;
            }
            pv.InvalidatePlot();

            tboxLog.Text = sb.ToString();
        }
Пример #4
0
            public MainWindow() : base(new[]
            {
                "resm:OxyPlot.Avalonia.Themes.Default.xaml?assembly=OxyPlot.Avalonia"
            })
            {
                Title = csv_pathfilename;
                string hdr = "";

                using (var sr = new StreamReader(csv_pathfilename))
                {
                    hdr = sr.ReadLine();
                }
                var hdr_ss = hdr.Split(',');
                var cols   = new List <int>();

                foreach (var chanFilter in chansFilter.Split(','))
                {
                    int idx = -1;
                    for (int i = 0; i < hdr_ss.Length; ++i)
                    {
                        if (hdr_ss[i].Trim().StripBegin('"').StripEnd('"') == chanFilter.Trim().StripBegin('"').StripEnd('"'))
                        {
                            idx = i;
                            break;
                        }
                    }
                    if (idx != -1)
                    {
                        cols.Add(idx);
                    }
                }

                if (cols.Count == 0)
                {
                    System.Console.WriteLine($"no matching cols");
                    Environment.Exit(1);
                }

                var grRoot = new Grid()
                {
                    Margin = new Thickness(10)
                }; this.Content = grRoot;

                pv       = new PlotView();
                pv.Model = new PlotModel();
                grRoot.Children.Add(pv);

                var series = new List <OxyPlot.Series.LineSeries>();

                foreach (var col in cols)
                {
                    var csv_data = new List <CsvItem>();
                    using (var sr = new StreamReader(csv_pathfilename))
                    {
                        sr.ReadLine();
                        while (!sr.EndOfStream)
                        {
                            var str = sr.ReadLine();
                            var ss  = str.Split(',');
                            csv_data.Add(new CsvItem {
                                t = ss[0].InvDoubleParse(), v = ss[col].InvDoubleParse() != 0
                            });
                        }
                    }
                    CsvItem periodBegin = null;
                    foreach (var x in csv_data.WithPrev())
                    {
                        if (x.item.v)
                        {
                            if (periodBegin == null)
                            {
                                periodBegin = x.item;
                            }
                            if (x.prev != null && !x.prev.v)
                            {
                                x.item.prev           = periodBegin;
                                periodBegin.periodSec = x.item.t - periodBegin.t;
                                periodBegin           = x.item;
                            }
                        }
                    }

                    var speed_items = csv_data
                                      .Where(r => r.periodSec > 0)
                                      .Select(x => new PlotData(
                                                  x.t + x.periodSec / 2,
                                                  1.0 / x.periodSec
                                                  ))
                                      .OrderBy(w => w.x);

                    var f1 = new OxyPlot.Series.LineSeries()
                    {
                        Title      = hdr_ss[col] + $" ({speed_items.Count()}pts)",
                        DataFieldX = "x",
                        DataFieldY = "y",

                        ItemsSource = speed_items
                    };
                    pv.Model.Series.Add(f1);
                }

                pv.ResetAllAxes();
                pv.InvalidatePlot();
            }