using HMI.Base;
|
using HMI.Core.Util;
|
using HMI.UI.Util;
|
using HMI.Util;
|
using Microsoft.Web.WebView2.Core;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.Data;
|
using System.Drawing;
|
using System.IO;
|
using System.Linq;
|
using System.Threading.Tasks;
|
using System.Windows;
|
using System.Windows.Controls;
|
|
namespace Plugin.DataBoard
|
{
|
/// <summary>
|
/// UserControl1.xaml 的交互逻辑
|
/// </summary>
|
public partial class DataBoard : PluginControl
|
{
|
public DataBoard()
|
{
|
DataContext = this;
|
InitializeComponent();
|
webview2.DefaultBackgroundColor = Color.Transparent;//Color.FromArgb(243, 249, 255);
|
}
|
|
private ObservableCollection<OptionData> _options = new ObservableCollection<OptionData> {
|
new OptionData { Name = LangUtil.Get("bd.today"), Value = "today" },
|
//new OptionData { Name = LangUtil.Get("bd.today"), Value = "today" },
|
new OptionData { Name = LangUtil.Get("bd.week"), Value = "week" },
|
new OptionData { Name = LangUtil.Get("bd.month"), Value = "month" }
|
};
|
|
public ObservableCollection<OptionData> Options
|
{
|
get { return _options; }
|
set { Set(ref _options, value); }
|
}
|
|
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
|
{
|
|
}
|
|
private void Button_Click(object sender, RoutedEventArgs e)
|
{
|
var btn = sender as Button;
|
DateTime start, end;
|
switch (btn.Name)
|
{
|
case "btn0":
|
start = dtp00.SelectedDateTime ?? DateTime.Now;
|
end = dtp01.SelectedDateTime ?? DateTime.Now;
|
RefreshChart0(start, end);
|
break;
|
case "btn1":
|
start = dtp10.SelectedDateTime ?? DateTime.Now;
|
end = dtp11.SelectedDateTime ?? DateTime.Now;
|
RefreshChart1(start, end);
|
break;
|
case "btn2":
|
start = dtp20.SelectedDateTime ?? DateTime.Now;
|
end = dtp21.SelectedDateTime ?? DateTime.Now;
|
RefreshChart2(start, end);
|
break;
|
case "btn3":
|
start = dtp30.SelectedDateTime ?? DateTime.Now;
|
end = dtp31.SelectedDateTime ?? DateTime.Now;
|
RefreshChart3(start, end);
|
break;
|
default:
|
break;
|
}
|
}
|
|
public static string[] GetDbFiles(string folderPath, DateTime startTime, DateTime endTime)
|
{
|
if (!Directory.Exists(folderPath))
|
{
|
return new string[0];
|
}
|
string startName = $"Data_{startTime.ToString("yyyyMMdd")}";
|
string endName = $"Data_{endTime.ToString("yyyyMMdd")}";
|
var oldFiles = Directory.GetFiles(folderPath, "Data_*.db");
|
oldFiles = oldFiles.Where(file =>
|
{
|
var fileName = Path.GetFileNameWithoutExtension(file);
|
bool flag = true;
|
if (startTime != null) flag &= (string.Compare(fileName, startName) == 1 || fileName == startName);
|
if (endTime != null) flag &= (string.Compare(endName, fileName) == 1 || fileName == endName);
|
return flag;
|
}).ToArray();
|
|
return oldFiles;
|
}
|
|
|
private List<SerialData> SelectSerialDataByTime(DateTime start, DateTime end)
|
{
|
var s1 = DateTime.Now;
|
string[] files = GetDbFiles(BaseFolder, start, end);
|
if (files == null || files.Length <= 0)
|
{
|
return new List<SerialData>();
|
}
|
string sql = $"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' ORDER BY time DESC;";
|
|
DataTable dt = new DataTable();
|
foreach (string file in files)
|
{
|
using (SqliteHelper helper = new SqliteHelper(file))
|
{
|
dt.Merge(helper.GetDataTable(sql));
|
}
|
}
|
var s2 = DateTime.Now;
|
log.Info($"SelectSerialDataByTime Cast: {(s2 - s1).TotalMilliseconds}");
|
var data = BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
|
log.Info($"Bean Cast: {(DateTime.Now - s2).TotalMilliseconds}");
|
return data;
|
}
|
|
private List<SerialData> SelectResultDataByTime(DateTime start, DateTime end)
|
{
|
string[] files = GetDbFiles(BaseFolder, start, end);
|
if (files == null || files.Length <= 0)
|
{
|
return new List<SerialData>();
|
}
|
string sql = $"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}';";
|
|
DataTable dt = new DataTable();
|
foreach (string file in files)
|
{
|
using (SqliteHelper helper = new SqliteHelper(file))
|
{
|
var temp = helper.GetDataTable(sql);
|
dt.Merge(temp);
|
}
|
}
|
return BeanUtil.ReadBeanFromDataTable<SerialData>(dt);
|
}
|
|
private void webview2_Loaded(object sender, RoutedEventArgs e)
|
{
|
string path = Path.Combine(PathHelper.AppFolder, "Libs", "Static", "test.html");
|
webview2.Source = new Uri(path);
|
}
|
|
private void Webview2_NavigationCompleted(object sender, CoreWebView2NavigationCompletedEventArgs e)
|
{
|
cb0.SelectedIndex = 0;
|
cb1.SelectedIndex = 0;
|
cb2.SelectedIndex = 0;
|
cb3.SelectedIndex = 0;
|
}
|
|
private void webview2_SizeChanged(object sender, SizeChangedEventArgs e)
|
{
|
var width = this.webview2.ActualWidth - 100;
|
var height = this.webview2.ActualHeight;
|
webview2.CoreWebView2?.ExecuteScriptAsync($"resize({width},{height})");
|
}
|
|
//private void RefreshChart0(DateTime start, DateTime end)
|
//{
|
// dtp00.SelectedDateTime = start;
|
// dtp01.SelectedDateTime = end;
|
// Task.Run(() =>
|
// {
|
// try
|
// {
|
// var st = DateTime.Now;
|
// List<SerialData> datas = SelectSerialDataByTime(start, end);
|
// log.Info($"0 Select Data cast: {(DateTime.Now-st).TotalMilliseconds}");
|
|
// datas.OrderByDescending(e => e.time);
|
// int all = 0, output = 0;
|
// HashSet<string> snCache = new HashSet<string>();
|
// foreach (var data in datas)
|
// {
|
// if (snCache.Contains(data.sn)) continue;
|
// snCache.Add(data.sn);
|
// all++;
|
// if (data.status == "Passed") output++;
|
// }
|
// var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
|
// Dispatcher.BeginInvoke(new Action(() =>
|
// {
|
// webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
|
// }));
|
// }
|
// catch (Exception ex)
|
// {
|
// log.Error("RefreshChart0 Error.", ex);
|
// ToastHelper.Error("表1刷新失败!");
|
// }
|
// });
|
//}
|
|
private void RefreshChart0(DateTime start, DateTime end)
|
{
|
dtp00.SelectedDateTime = start;
|
dtp01.SelectedDateTime = end;
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('加载中,请稍后...')");
|
}));
|
List<SerialData> datas = SelectResultDataByTime(start, end);
|
datas.OrderByDescending(e => e.time);
|
int all = 0, output = 0;
|
HashSet<string> snCache = new HashSet<string>();
|
foreach (var data in datas)
|
{
|
if (snCache.Contains(data.sn)) continue;
|
snCache.Add(data.sn);
|
all++;
|
if (data.result == "Passed") output++;
|
}
|
var fields = $"['{this.lang("bd.input")}','{this.lang("bd.output")}']";
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart0({fields}, [{all},{output}])");
|
}));
|
}
|
catch (Exception ex)
|
{
|
log.Error("RefreshChart0 Error.", ex);
|
ToastHelper.Error("表1刷新失败!");
|
}
|
});
|
}
|
|
private void RefreshChart1(DateTime start, DateTime end)
|
{
|
dtp10.SelectedDateTime = start;
|
dtp11.SelectedDateTime = end;
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('加载中,请稍后...')");
|
}));
|
List<SerialData> datas = SelectResultDataByTime(start, end);
|
|
datas = datas.OrderByDescending(e => e.time).ToList();
|
Dictionary<string, int?> pieData = new Dictionary<string, int?> {
|
{ "Passed",0},
|
{ "Failed",0},
|
//{ "Action",0},
|
//{ "Wait",0},
|
};
|
//if (datas == null || datas.Count <= 0)
|
//{
|
// pieData = new Dictionary<string, int?> {
|
// { "Passed",null},
|
// { "Failed",null},
|
//};
|
//}
|
|
HashSet<string> snCache = new HashSet<string>();
|
foreach (var data in datas)
|
{
|
if (snCache.Contains(data.sn)) continue;
|
snCache.Add(data.sn);
|
if (pieData.ContainsKey(data.result))
|
{
|
pieData[data.result]++;
|
}
|
}
|
string res = "[";
|
foreach (var key in pieData.Keys)
|
{
|
res += $"{{name:'{key}',value:{pieData[key]}}},";
|
}
|
res += "]";
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart1({res})");
|
}));
|
}
|
catch (Exception ex)
|
{
|
log.Error("RefreshChart1 Error.", ex);
|
ToastHelper.Error("表2刷新失败!");
|
}
|
});
|
}
|
|
//private void RefreshChart2(DateTime start, DateTime end)
|
//{
|
// dtp20.SelectedDateTime = start;
|
// dtp21.SelectedDateTime = end;
|
// List<SerialData> datas = SelectSerialDataByTime(start, end);
|
|
// var groups =
|
// datas.Where(e => e.status == "Passed" || e.status == "Failed").GroupBy(d => d.time.ToString("yyyy-MM-dd"));
|
|
// Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
|
|
// foreach (var group in groups)
|
// {
|
// Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
|
// double all = 0, oneTimePass = 0, passed = 0;
|
// var groupDatas = group.ToList();
|
// groupDatas = groupDatas.OrderBy(e => e.time).ToList();
|
|
// foreach (var data in groupDatas)
|
// {
|
// if (snStatusCache.ContainsKey(data.sn))
|
// {
|
// if (snStatusCache[data.sn] != "Passed" && data.status == "Passed")
|
// {
|
// passed++;
|
// }
|
// else if (snStatusCache[data.sn] == "Passed" && data.status == "Passed")
|
// {
|
// if (oneTimePass > 0) oneTimePass--;
|
// }
|
// }
|
// else
|
// {
|
// all++;
|
// if (data.status == "Passed")
|
// {
|
// passed++;
|
// oneTimePass++;
|
// }
|
// snStatusCache.Add(data.sn, data.status);
|
// }
|
// }
|
// res.Add(group.Key, new PassRateData
|
// {
|
// time = group.Key,
|
// onePassRate = oneTimePass / all * 100,
|
// passRate = passed / all * 100,
|
// });
|
// }
|
|
|
|
// string fields = "[", vals0 = "[", vals1 = "[";
|
// foreach (var key in res.Keys)
|
// {
|
// fields += $"'{key}',";
|
// vals0 += $"{res[key].onePassRate},";
|
// vals1 += $"{res[key].passRate},";
|
// }
|
// fields += "]";
|
// vals0 += "]";
|
// vals1 += "]";
|
// var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
|
// webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
|
//}
|
|
private void RefreshChart2(DateTime start, DateTime end)
|
{
|
dtp20.SelectedDateTime = start;
|
dtp21.SelectedDateTime = end;
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('加载中,请稍后...')");
|
}));
|
List<SerialData> datas = SelectResultDataByTime(start, end);
|
|
var groups =
|
datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
|
|
Dictionary<string, PassRateData> res = new Dictionary<string, PassRateData>();
|
|
foreach (var group in groups)
|
{
|
Dictionary<string, string> snStatusCache = new Dictionary<string, string>();
|
double all = 0, oneTimePass = 0, passed = 0;
|
var groupDatas = group.ToList();
|
groupDatas = groupDatas.OrderByDescending(e => e.time).ToList();
|
|
foreach (var data in groupDatas)
|
{
|
if (!snStatusCache.ContainsKey(data.sn))
|
{
|
snStatusCache.Add(data.sn, data.result);
|
all++;
|
if (data.result == "Passed")
|
{
|
passed++;
|
oneTimePass++;
|
}
|
}
|
else
|
{
|
if (snStatusCache[data.sn] == "Passed")
|
{
|
if (oneTimePass > 0) oneTimePass--;
|
snStatusCache[data.sn] = "NoOnePass";
|
}
|
}
|
}
|
res.Add(group.Key, new PassRateData
|
{
|
time = group.Key,
|
onePassRate = oneTimePass / all * 100,
|
passRate = passed / all * 100,
|
});
|
}
|
|
string fields = "[", vals0 = "[", vals1 = "[";
|
foreach (var key in res.Keys)
|
{
|
fields += $"'{key}',";
|
vals0 += $"{res[key].onePassRate},";
|
vals1 += $"{res[key].passRate},";
|
}
|
fields += "]";
|
vals0 += "]";
|
vals1 += "]";
|
var names = $"['{this.lang("bd.onePassRate")}','{this.lang("bd.passRate")}']";
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart2({fields},{names},{vals0},{vals1})");
|
}));
|
}
|
catch (Exception ex)
|
{
|
log.Error("RefreshChart2 Error.", ex);
|
ToastHelper.Error("表3刷新失败!");
|
}
|
});
|
}
|
|
private void RefreshChart3(DateTime start, DateTime end)
|
{
|
dtp30.SelectedDateTime = start;
|
dtp31.SelectedDateTime = end;
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('加载中,请稍后...')");
|
}));
|
var st = DateTime.Now;
|
List<SerialData> datas = SelectSerialDataByTime(start, end);
|
var s2 = DateTime.Now;
|
log.Info($"RefreshChart3 Data Cast {(s2 - st).TotalMilliseconds}");
|
|
Dictionary<string, SimpleData> pieData = new Dictionary<string, SimpleData>();
|
List<SimpleData> datasource = new List<SimpleData>();
|
//HashSet<string> snCache = new HashSet<string>();
|
|
foreach (var data in datas)
|
{
|
//if (snCache.Contains(data.sn)) continue;
|
if (data.status != "Failed") continue;
|
if (pieData.ContainsKey(data.step))
|
{
|
pieData[data.step].Value++;
|
}
|
else
|
{
|
pieData[data.step] = new SimpleData
|
{
|
Name = data.step,
|
Value = 1
|
};
|
datasource.Add(pieData[data.step]);
|
}
|
}
|
datasource = datasource.OrderByDescending(e => e.Value).ToList();
|
if (datasource.Count > 10)
|
{
|
datasource = datasource.Take(10).ToList();
|
}
|
var s3 = DateTime.Now;
|
log.Info($"RefreshChart3 Build {(s3 - s2).TotalMilliseconds}");
|
|
string names = string.Empty, vals = string.Empty;
|
foreach (var data in datasource)
|
{
|
names += $"'{data.Name}',";
|
vals += $"{data.Value},";
|
}
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
webview2.CoreWebView2?.ExecuteScriptAsync($"drawChart3([{names}],[{vals}])");
|
}));
|
}
|
catch (Exception ex)
|
{
|
log.Error("RefreshChart3 Error.", ex);
|
ToastHelper.Error("表4刷新失败!");
|
}
|
});
|
}
|
|
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
{
|
ComboBox cb = sender as ComboBox;
|
string val = (e.AddedItems[0] as OptionData)?.Value?.ToString();
|
DateTime start, end;
|
if (val == "today")
|
{
|
DateUtil.GetDayTime(out start, out end);
|
}
|
else if (val == "week")
|
{
|
DateUtil.GetWeekTime(out start, out end);
|
}
|
else
|
{
|
DateUtil.GetMonthTime(out start, out end);
|
}
|
|
switch (cb.Name)
|
{
|
case "cb0":
|
RefreshChart0(start, end);
|
break;
|
case "cb1":
|
RefreshChart1(start, end);
|
break;
|
case "cb2":
|
RefreshChart2(start, end);
|
break;
|
case "cb3":
|
RefreshChart3(start, end);
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
}
|