#c_sharp #net #winforms #oxyplot
Пишу академическую программу - монитор частоты. Для печати графиков использую Nuget Oxylot. Не могу понять как мне напечатать график в реальном времени. Например изменения раз в секунду. По оси X должно быть время, по оси Y - значение double, изменяющееся от 0 до 50.00 единиц (частота в Гц). Взял семпл из документации, а как туда значение вставить и обновлять по времени не понимаю... Вот класс графика: public class Plotter { private PlotModel model; private DateTime startDate = DateTime.Now.AddDays(-10); private DateTime endDate = DateTime.Now; private readonly Listcolors = new List { OxyColors.Green, OxyColors.IndianRed, OxyColors.Coral, OxyColors.Chartreuse, OxyColors.Azure }; private readonly List markerTypes = new List { MarkerType.Plus, MarkerType.Star, MarkerType.Diamond, MarkerType.Triangle, MarkerType.Cross }; public Plotter() { model = new PlotModel { Title = "DateTimeAxis" }; } public PlotModel PrintChart() { var minValue = DateTimeAxis.ToDouble(startDate); var maxValue = DateTimeAxis.ToDouble(endDate); model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, Minimum = minValue, Maximum = maxValue, StringFormat = "HH:mm" }); return model; }} В основном окошке: public void PrintChart() { Plotter pt = new Plotter(); frGraph.Model = pt.PrintChart(); } По событию кнопки разрешаю печать: private void startDrawing_Click(object sender, EventArgs e) { PrintChart(); } И по таймеру пытаюсь обновлять (не уверен, что делаю правильно..) private void InitializeTimerForChart() { tickCount.Interval = References.TIMER_INTERVAL; // (1000 мс) this.tickCount.Tick += new System.EventHandler(this.tickCount_Tick); tickCount.Enabled = true; } private void tickCount_Tick(object sender, EventArgs e) { if (InvokeRequired) { Invoke((MethodInvoker)delegate () { frGraph.Invalidate();//PrintChart(); }); } } На данный момент класс просто показывает на форме модель с осями, на оси Y текущее время.
Ответы
Ответ 1
В общем получилось создать линейный график без обновлений. Обновлять буду также через таймер раз в секунду. public PlotModel PrintChart() { var minValue = DateTimeAxis.ToDouble(startDate); var maxValue = DateTimeAxis.ToDouble(endDate); model.Axes.Add(new DateTimeAxis { Position = AxisPosition.Bottom, Minimum = minValue, Maximum = maxValue, StringFormat = "HH:mm" }); var leftAxisY = new LinearAxis { Position = AxisPosition.Left }; model.Axes.Add(leftAxisY); var lineSeries = new LineSeries { Title = "Линейный график", StrokeThickness = 3, LineStyle = LineStyle.Automatic, MarkerType = MarkerType.Circle, MarkerSize = 5, MarkerStroke = OxyColors.White, MarkerFill = OxyColors.Automatic, MarkerStrokeThickness = 1.5, }; for (int i = 0; i < 50; i++) { lineSeries.Points.Add(new DataPoint(minValue, i)); } model.Series.Add(lineSeries); return model; }Ответ 2
Отвечу, может кому-то понадобится. Когда добавляете серию в график, используйте свойство series.ItemSource private void AddSeries(string Name, OxyColor Color, string AxisKey, ListBuffer) { var series = new LineSeries(); series.Title = Name; series.Color = Color; series.YAxisKey = AxisKey; series.ItemsSource = Buffer; Model.Series.Add(series); } Buffer здесь это коллекция данных, в который вы будете складывать собираемые точки. Обновлять следующим образом: Buffer.Add(new DataPoint(x, y)); // здесь можете делать с коллекцией что // хотите: удалять, добавлять, очищать Model.InvalidatePlot(true); Да, тип таймера имеет значение: Threading.Timer каждый обратный вызов запускает в новом потоке, DispatcherTimer в потоке диспетчера (для простых задач наиболее удобен, косяков меньше)
Комментариев нет:
Отправить комментарий