using HMI.Base;
using HMI.Core.Entity;
using HMI.Core.Manager;
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
{
///
/// UserControl1.xaml 的交互逻辑
///
public partial class DataBoard : PluginControl
{
public DataBoard()
{
DataContext = this;
InitializeComponent();
webview2.DefaultBackgroundColor = Color.Transparent;//Color.FromArgb(243, 249, 255);
}
private ObservableCollection _options = new ObservableCollection {
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 Options
{
get { return _options; }
set { Set(ref _options, value); }
}
private string iniFile;
public override void InitFinish()
{
iniFile = Path.Combine(BaseFolder, "Config.ini");
if (!File.Exists(iniFile))
{
File.Create(iniFile);
}
LoadProduct();
}
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
{
}
private void LoadProduct()
{
List products = ProductManager.GetProducts>()
?? new List();
this.modelSelect.Items.Clear();
List productSource = new List();
foreach (var prd in products)
{
this.modelSelect.Items.Add(prd.Name);
productSource.Add(prd.Name);
}
string model = IniFileHelper.ReadIniData("Config", "Model", "", iniFile);
if (!string.IsNullOrEmpty(model))
{
this.modelSelect.SelectedItem = model;
}
else if (products.Count > 0)
{
this.modelSelect.SelectedIndex = 0;
}
}
private void RefreshAll()
{
try
{
var start0 = dtp00.SelectedDateTime ?? DateTime.Now;
var end0 = dtp01.SelectedDateTime ?? DateTime.Now;
RefreshChart0(start0, end0);
}
catch { }
try
{
var start1 = dtp10.SelectedDateTime ?? DateTime.Now;
var end1 = dtp11.SelectedDateTime ?? DateTime.Now;
RefreshChart1(start1, end1);
}
catch { }
try
{
var start2 = dtp20.SelectedDateTime ?? DateTime.Now;
var end2 = dtp21.SelectedDateTime ?? DateTime.Now;
RefreshChart2(start2, end2);
}
catch { }
try
{
var start3 = dtp30.SelectedDateTime ?? DateTime.Now;
var end3 = dtp31.SelectedDateTime ?? DateTime.Now;
RefreshChart3(start3, end3);
}
catch { }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
DateTime start, end;
switch (btn.Name)
{
case "btnAll":
RefreshAll();
break;
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 SelectSerialDataByTime(string model, DateTime start, DateTime end)
{
var s1 = DateTime.Now;
string[] files = GetDbFiles(BaseFolder, start, end);
if (files == null || files.Length <= 0)
{
return new List();
}
string segment = string.Empty;
if (!string.IsNullOrEmpty(model))
{
segment = $"AND model = '{model}'";
}
string sql = $@"SELECT * FROM serialData WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}'
{segment} 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(dt);
log.Info($"Bean Cast: {(DateTime.Now - s2).TotalMilliseconds}");
return data;
}
private List SelectResultDataByTime(string model, DateTime start, DateTime end)
{
string[] files = GetDbFiles(BaseFolder, start, end);
if (files == null || files.Length <= 0)
{
return new List();
}
string segment = string.Empty;
if (!string.IsNullOrEmpty(model))
{
segment = $"AND model = '{model}'";
}
string sql = $@"SELECT * FROM testResult WHERE time BETWEEN '{start:yyyy-MM-dd HH:mm:ss}' AND '{end:yyyy-MM-dd HH:mm:ss}' {segment};";
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(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 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 snCache = new HashSet();
// 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;
string model = modelSelect.SelectedItem?.ToString();
Task.Run(() =>
{
try
{
Dispatcher.BeginInvoke(new Action(() =>
{
webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('加载中,请稍后...')");
}));
List datas = SelectResultDataByTime(model, start, end);
datas.OrderByDescending(e => e.time);
int all = 0, output = 0;
HashSet snCache = new HashSet();
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;
string model = modelSelect.SelectedItem?.ToString();
Task.Run(() =>
{
try
{
Dispatcher.BeginInvoke(new Action(() =>
{
webview2.CoreWebView2?.ExecuteScriptAsync($"loading1('加载中,请稍后...')");
}));
List datas = SelectResultDataByTime(model, start, end);
datas = datas.OrderByDescending(e => e.time).ToList();
Dictionary pieData = new Dictionary {
{ "Passed",0},
{ "Failed",0},
//{ "Action",0},
//{ "Wait",0},
};
//if (datas == null || datas.Count <= 0)
//{
// pieData = new Dictionary {
// { "Passed",null},
// { "Failed",null},
//};
//}
HashSet snCache = new HashSet();
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 datas = SelectSerialDataByTime(start, end);
// var groups =
// datas.Where(e => e.status == "Passed" || e.status == "Failed").GroupBy(d => d.time.ToString("yyyy-MM-dd"));
// Dictionary res = new Dictionary();
// foreach (var group in groups)
// {
// Dictionary snStatusCache = new Dictionary();
// 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;
string model = modelSelect.SelectedItem?.ToString();
Task.Run(() =>
{
try
{
Dispatcher.BeginInvoke(new Action(() =>
{
webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('加载中,请稍后...')");
}));
List datas = SelectResultDataByTime(model, start, end);
var groups =
datas.GroupBy(d => d.time.ToString("yyyy-MM-dd"));
Dictionary res = new Dictionary();
foreach (var group in groups)
{
Dictionary snStatusCache = new Dictionary();
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;
string model = modelSelect.SelectedItem?.ToString();
Task.Run(() =>
{
try
{
Dispatcher.BeginInvoke(new Action(() =>
{
webview2.CoreWebView2?.ExecuteScriptAsync($"loading3('加载中,请稍后...')");
}));
var st = DateTime.Now;
List datas = SelectSerialDataByTime(model, start, end);
var s2 = DateTime.Now;
log.Info($"RefreshChart3 Data Cast {(s2 - st).TotalMilliseconds}");
Dictionary pieData = new Dictionary();
List datasource = new List();
//HashSet snCache = new HashSet();
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;
}
}
private void modelSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
IniFileHelper.WriteIniData("Config", "Model", e.AddedItems[0].ToString(), iniFile);
}
}
}
}