Skip to content

Commit 8fc0b69

Browse files
author
Georgy Levchenko
committed
Added LegendChart AnalyticsWindow.
1 parent fdccd71 commit 8fc0b69

File tree

6 files changed

+275
-89
lines changed

6 files changed

+275
-89
lines changed

src/Modules/SmartThermo.Modules.Analytics/ViewModels/AnalyticsWindowViewModel.cs

Lines changed: 150 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
using System;
1313
using System.Collections.Generic;
1414
using System.Collections.ObjectModel;
15-
using System.Diagnostics;
1615
using System.Drawing;
1716
using System.Globalization;
1817
using System.Linq;
18+
using System.Threading;
1919
using System.Threading.Tasks;
2020
using System.Windows;
2121
using System.Windows.Input;
@@ -26,21 +26,35 @@ public class AnalyticsWindowViewModel : RegionViewModelBase
2626
{
2727
#region Field
2828

29+
private readonly List<SignalPlotXYConst<double, double>> _signalPlotXyConst = new List<SignalPlotXYConst<double, double>>();
2930
private readonly List<int> _groupSensorId = new List<int>();
31+
private readonly Timer _timer;
3032

33+
private List<Color> _colors = new List<Color>()
34+
{
35+
Color.FromArgb(0x00, 0x3f, 0x5c),
36+
Color.FromArgb(0x44, 0x4e, 0x86),
37+
Color.FromArgb(0x95, 0x51, 0x96),
38+
Color.FromArgb(0xdd, 0x51, 0x82),
39+
Color.FromArgb(0xff, 0x6e, 0x54),
40+
Color.FromArgb(0xff, 0xa6, 0x00)
41+
};
3142
private WpfPlot _plotControl;
3243
private Plot _plot;
3344
private VLine _vLine;
34-
private SignalPlotXYConst<double, double> _signalPlotXyConst;
3545

3646
private int _sensorGroupSelected;
3747
private ObservableCollection<ItemDescriptor<bool>> _groupCheckItems = new ObservableCollection<ItemDescriptor<bool>>();
48+
private ObservableCollection<ItemDescriptor<System.Windows.Media.Brush>> _legendItems = new ObservableCollection<ItemDescriptor<System.Windows.Media.Brush>>();
49+
private ObservableCollection<int> _legendValueItems = new ObservableCollection<int>();
3850
private string _dateCreateSession;
51+
private string _dateLegend;
3952
private Visibility _showLoadIndicator = Visibility.Hidden;
4053
private int _currentSessionId;
4154
private bool _isLoadCurrentSession = true;
4255
private bool _isLoadData;
43-
56+
private bool _isUpdateChart;
57+
4458
#endregion
4559

4660
#region Property
@@ -65,12 +79,30 @@ public ObservableCollection<ItemDescriptor<bool>> GroupCheckItems
6579
set => SetProperty(ref _groupCheckItems, value);
6680
}
6781

82+
public ObservableCollection<ItemDescriptor<System.Windows.Media.Brush>> LegendItems
83+
{
84+
get => _legendItems;
85+
set => SetProperty(ref _legendItems, value);
86+
}
87+
88+
public ObservableCollection<int> LegendValueItems
89+
{
90+
get => _legendValueItems;
91+
set => SetProperty(ref _legendValueItems, value);
92+
}
93+
6894
public string DateCreateSession
6995
{
7096
get => _dateCreateSession;
7197
set => SetProperty(ref _dateCreateSession, value);
7298
}
7399

100+
public string DateLegend
101+
{
102+
get => _dateLegend;
103+
set => SetProperty(ref _dateLegend, value);
104+
}
105+
74106
public Visibility ShowLoadIndicator
75107
{
76108
get => _showLoadIndicator;
@@ -89,13 +121,14 @@ public AnalyticsWindowViewModel(IRegionManager regionManager, IDeviceConnector d
89121
INotifications notifications, IDialogService dialogService)
90122
: base(regionManager, deviceConnector, notifications, dialogService)
91123
{
124+
_timer = new Timer((state) => _isUpdateChart = false, 0, Timeout.Infinite, Timeout.Infinite);
125+
92126
SensorGroups = Enumerable.Range(0, 6)
93127
.Select(x => new ItemDescriptor<int>($"Группа №{x + 1}", x))
94128
.ToList();
95129
SensorGroupSelected = 0;
96-
97130
GroupCheckItems.AddRange(Enumerable.Range(0, 6)
98-
.Select(x => new ItemDescriptor<bool>($"Датчик №{x + 1}", true))
131+
.Select(x => new ItemDescriptor<bool>($"Датчик №{x + 1}", true, x))
99132
.ToList());
100133

101134
InitChart();
@@ -112,21 +145,17 @@ public AnalyticsWindowViewModel(IRegionManager regionManager, IDeviceConnector d
112145
private void InitChart()
113146
{
114147
PlotControl = new WpfPlot();
115-
//PlotControl.MouseMove += PlotControl_MouseMove;
148+
PlotControl.MouseMove += PlotControl_MouseMove;
116149

117150
_plot = PlotControl.Plot;
118151
_plot.Style(
119-
dataBackground: Color.FromArgb(31, 31, 31),
152+
dataBackground: Color.FromArgb(31, 31, 31),
120153
figureBackground: Color.FromArgb(31, 31, 31),
121-
grid: Color.FromArgb(121, 121, 121),
154+
grid: Color.FromArgb(121, 121, 121),
122155
tick: Color.FromArgb(170, 170, 170));
123156
_plot.XAxis.TickLabelStyle(fontSize: 12);
124157
_plot.XAxis.DateTimeFormat(true);
125158
_plot.YAxis.TickLabelStyle(fontSize: 12);
126-
127-
var legend = _plot.Legend();
128-
legend.Padding = 8;
129-
legend.FontSize = 14;
130159
}
131160

132161
private async void InitChartValueAsync()
@@ -188,6 +217,8 @@ private async Task GetSensorDataAsync()
188217
{
189218
Notifications.ShowInformation("Нет данных для анализа.");
190219

220+
LegendItems.Clear();
221+
LegendValueItems.Clear();
191222
_plot.Clear();
192223
_isLoadData = false;
193224
return;
@@ -206,33 +237,67 @@ private async Task GetSensorDataAsync()
206237
var result = getItemsTask.Result;
207238

208239
var dateTime = result.Select(x => x.DataTime.ToOADate()).ToArray();
240+
DateLegend = result[0].DataTime.ToString();
241+
242+
LegendItems.Clear();
243+
LegendValueItems.Clear();
244+
foreach (var item in GroupCheckItems.Where(x => x.Value))
245+
LegendItems.Add(new ItemDescriptor<System.Windows.Media.Brush>($"Датчик №{item.Id + 1}", _colors[item.Id].ToBrush()));
209246

210247
_plot.Clear();
248+
_signalPlotXyConst.Clear();
249+
211250
if (GroupCheckItems[0].Value)
212-
_signalPlotXyConst = _plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value1).ToArray(),
213-
color: Color.FromArgb(0x00, 0x3f, 0x5c), label: "Датчик №1");
251+
{
252+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
253+
result.Select(x => (double)x.Value1).ToArray(),
254+
_colors[0]));
255+
LegendValueItems.Add(result[0].Value1);
256+
}
214257
if (GroupCheckItems[1].Value)
215-
_plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value2).ToArray(),
216-
color: Color.FromArgb(0x44, 0x4e, 0x86), label: "Датчик №2");
258+
{
259+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
260+
result.Select(x => (double)x.Value2).ToArray(),
261+
_colors[1]));
262+
LegendValueItems.Add(result[0].Value2);
263+
}
217264
if (GroupCheckItems[2].Value)
218-
_plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value3).ToArray(),
219-
color: Color.FromArgb(0x95, 0x51, 0x96), label: "Датчик №3");
265+
{
266+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
267+
result.Select(x => (double)x.Value3).ToArray(),
268+
_colors[2]));
269+
LegendValueItems.Add(result[0].Value3);
270+
}
220271
if (GroupCheckItems[3].Value)
221-
_plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value4).ToArray(),
222-
color: Color.FromArgb(0xdd, 0x51, 0x82), label: "Датчик №4");
272+
{
273+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
274+
result.Select(x => (double)x.Value4).ToArray(),
275+
_colors[3]));
276+
LegendValueItems.Add(result[0].Value4);
277+
}
223278
if (GroupCheckItems[4].Value)
224-
_plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value5).ToArray(),
225-
color: Color.FromArgb(0xff, 0x6e, 0x54), label: "Датчик №5");
279+
{
280+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
281+
result.Select(x => (double)x.Value5).ToArray(),
282+
_colors[4]));
283+
LegendValueItems.Add(result[0].Value5);
284+
}
226285
if (GroupCheckItems[5].Value)
227-
_plot.AddSignalXYConst(dateTime, result.Select(x => (double) x.Value6).ToArray(),
228-
color: Color.FromArgb(0xff, 0xa6, 0x00), label: "Датчик №6");
286+
{
287+
_signalPlotXyConst.Add(_plot.AddSignalXYConst(dateTime,
288+
result.Select(x => (double)x.Value6).ToArray(),
289+
_colors[5]));
290+
LegendValueItems.Add(result[0].Value6);
291+
}
229292
_vLine = _plot.AddVerticalLine(dateTime[0], color: Color.Red, style: LineStyle.Dash);
230-
293+
231294
_plot.AxisAutoX();
232-
_plot.SetAxisLimitsY(0, 165);
295+
_plot.SetAxisLimitsY(0, 165);
233296
PlotControl.Render();
234297

235298
_isLoadData = true;
299+
_timer.Change(TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(50));
300+
236301
ShowLoadIndicator = Visibility.Hidden;
237302
}
238303

@@ -252,55 +317,55 @@ private void SelectSessionExecute()
252317
Notifications.ShowInformation("Операция прервана пользователем.");
253318
break;
254319
case ButtonResult.OK:
255-
{
256-
var isLoadCurrentSession = r.Parameters.GetValue<bool>("CheckCurrentSession");
257-
_currentSessionId = r.Parameters.GetValue<int>("SessionItemSelected");
258-
259-
if (isLoadCurrentSession)
260320
{
261-
if (_isLoadCurrentSession)
262-
return;
263-
264-
await GetIdGroupsSensorAsync();
265-
await GetSensorDataAsync();
321+
var isLoadCurrentSession = r.Parameters.GetValue<bool>("CheckCurrentSession");
322+
_currentSessionId = r.Parameters.GetValue<int>("SessionItemSelected");
266323

267-
Notifications.ShowSuccess("Загружена текущая сессия.");
268-
_isLoadCurrentSession = true;
269-
}
270-
else
271-
{
272-
var dataCreateTask = Task.Run(() =>
324+
if (isLoadCurrentSession)
273325
{
274-
using var context = new Context();
275-
return context.Sessions
276-
.Where(x => x.Id == _currentSessionId)
277-
.Select(x => x.DateCreate)
278-
.FirstOrDefault();
279-
});
280-
await Task.WhenAll(dataCreateTask);
281-
DateCreateSession = dataCreateTask.Result
282-
.Round(TimeSpan.FromSeconds(1))
283-
.ToString(CultureInfo.InvariantCulture);
284-
285-
var groupIdTask = Task.Run(() =>
326+
if (_isLoadCurrentSession)
327+
return;
328+
329+
await GetIdGroupsSensorAsync();
330+
await GetSensorDataAsync();
331+
332+
Notifications.ShowSuccess("Загружена текущая сессия.");
333+
_isLoadCurrentSession = true;
334+
}
335+
else
286336
{
287-
using var context = new Context();
288-
return context.GroupSensors
289-
.Where(x => x.SessionId == _currentSessionId)
290-
.Select(x => x.Id)
291-
.ToList();
292-
});
293-
await Task.WhenAll(groupIdTask);
294-
295-
_groupSensorId.Clear();
296-
_groupSensorId.AddRange(groupIdTask.Result);
297-
298-
await GetSensorDataAsync();
299-
Notifications.ShowSuccess($"Загружена сессия от {DateCreateSession}.");
300-
_isLoadCurrentSession = false;
337+
var dataCreateTask = Task.Run(() =>
338+
{
339+
using var context = new Context();
340+
return context.Sessions
341+
.Where(x => x.Id == _currentSessionId)
342+
.Select(x => x.DateCreate)
343+
.FirstOrDefault();
344+
});
345+
await Task.WhenAll(dataCreateTask);
346+
DateCreateSession = dataCreateTask.Result
347+
.Round(TimeSpan.FromSeconds(1))
348+
.ToString(CultureInfo.InvariantCulture);
349+
350+
var groupIdTask = Task.Run(() =>
351+
{
352+
using var context = new Context();
353+
return context.GroupSensors
354+
.Where(x => x.SessionId == _currentSessionId)
355+
.Select(x => x.Id)
356+
.ToList();
357+
});
358+
await Task.WhenAll(groupIdTask);
359+
360+
_groupSensorId.Clear();
361+
_groupSensorId.AddRange(groupIdTask.Result);
362+
363+
await GetSensorDataAsync();
364+
Notifications.ShowSuccess($"Загружена сессия от {DateCreateSession}.");
365+
_isLoadCurrentSession = false;
366+
}
367+
break;
301368
}
302-
break;
303-
}
304369
case ButtonResult.Abort:
305370
break;
306371
case ButtonResult.Ignore:
@@ -323,15 +388,27 @@ private void SelectSessionExecute()
323388

324389
private void PlotControl_MouseMove(object sender, MouseEventArgs e)
325390
{
326-
// TODO: Необходима задержка.
327391
if (!_isLoadData)
328392
return;
329393

394+
if (_isUpdateChart)
395+
return;
396+
330397
var (mouseCoordsX, _) = PlotControl.GetMouseCoordinates();
331-
var (pointX, _, _) = _signalPlotXyConst.GetPointNearestX(mouseCoordsX);
332-
_vLine.X = pointX;
398+
_legendValueItems.Clear();
399+
for (int i = 0; i < LegendItems.Count; i++)
400+
{
401+
var data = _signalPlotXyConst[i].GetPointNearestX(mouseCoordsX).y;
402+
_legendValueItems.Add((int)data);
403+
}
404+
405+
var result = _signalPlotXyConst[0].GetPointNearestX(mouseCoordsX).x;
406+
_vLine.X = result;
407+
DateLegend = DateTime.FromOADate(result).ToString();
333408

409+
_isUpdateChart = true;
334410
PlotControl.Render();
411+
RaisePropertyChanged(nameof(LegendItems));
335412
}
336413

337414
#endregion

0 commit comments

Comments
 (0)