using HMI.Base;
|
using HMI.Core.Entity;
|
using HMI.Core.Manager;
|
using HMI.Core.Setting;
|
using HMI.Core.Util;
|
using HMI.UI.Util;
|
using HMI.Util;
|
using LiveChartsCore;
|
using LiveChartsCore.Drawing;
|
using LiveChartsCore.Drawing.Layouts;
|
using LiveChartsCore.Kernel.Sketches;
|
using LiveChartsCore.SkiaSharpView;
|
using LiveChartsCore.SkiaSharpView.Drawing;
|
using LiveChartsCore.SkiaSharpView.Drawing.Geometries;
|
using LiveChartsCore.SkiaSharpView.Drawing.Layouts;
|
using LiveChartsCore.SkiaSharpView.Painting;
|
using LiveChartsCore.SkiaSharpView.SKCharts;
|
using LiveChartsCore.SkiaSharpView.VisualElements;
|
using Microsoft.Web.WebView2.Core;
|
using SkiaSharp;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
using System.Data;
|
using System.IO;
|
using System.Linq;
|
using System.Threading.Tasks;
|
using System.Windows;
|
using System.Windows.Controls;
|
|
namespace Plugin.DataBoard
|
{
|
public class CustomLegend : SKDefaultLegend
|
{
|
|
protected override Layout<SkiaSharpDrawingContext> GetLayout(LiveChartsCore.Chart chart)
|
{
|
var stackLayout = new StackLayout
|
{
|
Orientation = ContainerOrientation.Horizontal,
|
Padding = new Padding(0, 10, 0, 0),
|
HorizontalAlignment = Align.Start,
|
VerticalAlignment = Align.Middle,
|
};
|
|
foreach (var series in chart.Series.Where(x => x.IsVisibleAtLegend))
|
{
|
stackLayout.Children.Add(new LegendItem(series));
|
}
|
return stackLayout;
|
}
|
}
|
|
public class LegendItem : StackLayout
|
{
|
public LegendItem(ISeries series)
|
{
|
Orientation = ContainerOrientation.Horizontal;
|
Padding = new Padding(0);
|
VerticalAlignment = Align.Start;
|
HorizontalAlignment = Align.Middle;
|
Opacity = series.IsVisible ? 1 : 0.5f;
|
|
var miniature = (IDrawnElement<SkiaSharpDrawingContext>)series.GetMiniatureGeometry(null);
|
Children = new List<IDrawnElement<SkiaSharpDrawingContext>> {
|
miniature,
|
new LabelGeometry
|
{
|
Text = series.Name,
|
TextSize = 12,
|
Paint = new SolidColorPaint(SKColors.Black){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Padding = new Padding(5,0,10,0),
|
VerticalAlign = Align.Middle,
|
HorizontalAlign = Align.Start
|
}};
|
}
|
}
|
|
/// <summary>
|
/// UserControl1.xaml 的交互逻辑
|
/// </summary>
|
public partial class DataBoard : PluginControl
|
{
|
public DataBoard()
|
{
|
DataContext = this;
|
InitializeComponent();
|
//webview2.DefaultBackgroundColor = Color.Transparent;//Color.FromArgb(243, 249, 255);
|
}
|
|
private SolidColorPaint tooltipTextPaint = new SolidColorPaint(SKColors.Black)
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
};
|
public SolidColorPaint TooltipTextPaint
|
{
|
get => tooltipTextPaint;
|
set
|
{
|
Set(ref tooltipTextPaint, value);
|
}
|
}
|
#region chart0
|
|
public LabelVisual Chart0Title { get; set; } = new LabelVisual
|
{
|
Text = "投入产出统计",
|
TextSize = 20,
|
Paint = new SolidColorPaint(new SKColor(0, 0, 0))
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Padding = new LiveChartsCore.Drawing.Padding(15)
|
};
|
|
private ISeries[] chart0_series = new ISeries[] {
|
new ColumnSeries<int> {
|
Fill= new SolidColorPaint(new SKColor(34, 68, 139)),
|
DataLabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
|
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
|
Values = new int[]{ 0,0} }
|
};
|
|
public ISeries[] Chart0_series
|
{
|
get => chart0_series;
|
set
|
{
|
Set(ref chart0_series, value);
|
}
|
}
|
|
private ObservableCollection<Axis> chart0_yAxes = new ObservableCollection<Axis> {
|
new Axis
|
{
|
MinStep = 1,
|
MinLimit = 0,
|
LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
|
SeparatorsPaint = new SolidColorPaint
|
{
|
Color = SKColors.Black.WithAlpha(30),
|
StrokeThickness = 0.5f
|
},
|
TicksPaint = new SolidColorPaint
|
{
|
Color = SKColor.Empty,
|
StrokeThickness = 0
|
},
|
}
|
};
|
|
public ObservableCollection<Axis> Chart0_yAxes
|
{
|
get => chart0_yAxes;
|
set
|
{
|
Set(ref chart0_yAxes, value);
|
}
|
}
|
|
private Axis[] chart0_xAxes = new Axis[] {
|
new Axis
|
{
|
Labels = new string[]{"投入", "产出" },
|
LabelsPaint=new SolidColorPaint(new SKColor(0, 0, 0))
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
LabelsRotation = 0,
|
SeparatorsAtCenter = false,
|
TicksPaint = new SolidColorPaint(new SKColor(35, 35, 35)),
|
TicksAtCenter = true,
|
ForceStepToMin = true,
|
MinStep = 1
|
}
|
};
|
public Axis[] Chart0_xAxes
|
{
|
get => chart0_xAxes;
|
set
|
{
|
Set(ref chart0_xAxes, value);
|
}
|
}
|
#endregion
|
|
#region chart1
|
|
public LabelVisual Chart1Title { get; set; } = new LabelVisual
|
{
|
Text = "产品状态统计",
|
TextSize = 20,
|
Paint = new SolidColorPaint(new SKColor(0, 0, 0))
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Padding = new LiveChartsCore.Drawing.Padding(15)
|
};
|
|
public ISeries[] Chart1_series { get; set; } = new PieSeries<int>[]
|
{
|
new PieSeries<int> {
|
Name="Passed",
|
Values = new int[]{ 0},
|
DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
|
DataLabelsSize = 15,
|
DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Fill = new SolidColorPaint(new SKColor(0, 128, 0)),
|
DataLabelsFormatter =
|
point =>point.StackedValue.Total>0?
|
$"Passed\r\n计数:{point.Coordinate.PrimaryValue}\r\n占比:{point.StackedValue.Share:P2}":"",
|
ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"
|
},
|
new PieSeries<int> { Values = new int[]{ 0} ,
|
Name="Failed",
|
DataLabelsPosition = LiveChartsCore.Measure.PolarLabelsPosition.Outer,
|
DataLabelsSize = 15,
|
DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Fill = new SolidColorPaint(new SKColor(255, 0, 0)),
|
DataLabelsFormatter =
|
point =>point.StackedValue.Total>0?
|
$"Failed\r\n计数:{point.Coordinate.PrimaryValue}\r\n占比:{point.StackedValue.Share:P2}":"",
|
ToolTipLabelFormatter = point => $"{point.StackedValue.Share:P2}"},
|
};
|
|
#endregion
|
|
#region chart2
|
|
public LabelVisual Chart2Title { get; set; } = new LabelVisual
|
{
|
Text = "良率统计",
|
TextSize = 20,
|
Paint = new SolidColorPaint(new SKColor(0, 0, 0))
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Padding = new LiveChartsCore.Drawing.Padding(15)
|
};
|
|
public ISeries[] Chart2_series { get; set; } = new ISeries[]
|
{
|
new LineSeries<double> {
|
Name="直通率",
|
Values = new double[]{ 0},
|
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
|
DataLabelsFormatter =
|
point => $"直通率:{point.Coordinate.PrimaryValue:f2}%",
|
DataLabelsSize = 15,
|
DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Stroke = new SolidColorPaint(new SKColor(255,0,0)){
|
StrokeThickness = 2
|
},
|
Fill = null,
|
GeometryStroke = new SolidColorPaint(new SKColor(255,0,0)){
|
StrokeThickness = 2
|
},
|
GeometrySize=5
|
},
|
new LineSeries<double> {
|
Name="良率",
|
Values = new double[]{ 0},
|
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Bottom,
|
DataLabelsFormatter =
|
point => $"良率:{point.Coordinate.PrimaryValue:f2}%",
|
DataLabelsSize = 10,
|
DataLabelsPaint = new SolidColorPaint(new SKColor(30, 30, 30)){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Stroke = new SolidColorPaint(new SKColor(34, 68, 139)){
|
StrokeThickness = 2
|
},
|
GeometryStroke = new SolidColorPaint(new SKColor(34, 68, 139)){
|
StrokeThickness = 2
|
},
|
Fill = null,
|
},
|
};
|
|
private ObservableCollection<Axis> chart2_yAxes = new ObservableCollection<Axis> {
|
new Axis
|
{
|
LabelsPaint = new SolidColorPaint(new SKColor(0, 0, 0)),
|
SeparatorsPaint = new SolidColorPaint
|
{
|
Color = SKColors.Black.WithAlpha(30),
|
StrokeThickness = 0.5f
|
},
|
TicksPaint = new SolidColorPaint
|
{
|
Color = SKColor.Empty,
|
StrokeThickness = 0
|
},
|
MinLimit = 0
|
}
|
};
|
public ObservableCollection<Axis> Chart2_yAxes
|
{
|
get => chart2_yAxes;
|
set
|
{
|
Set(ref chart2_yAxes, value);
|
}
|
}
|
|
private ObservableCollection<ICartesianAxis> chart2_xAxes = new ObservableCollection<ICartesianAxis> {
|
new Axis
|
{
|
Labels = new string[]{"" },
|
}
|
};
|
|
public ObservableCollection<ICartesianAxis> Chart2_xAxes {
|
get => chart2_xAxes;
|
set {
|
Set(ref chart2_xAxes, value);
|
}
|
}
|
|
#endregion
|
|
#region chart3
|
|
public LabelVisual Chart3Title { get; set; } = new LabelVisual
|
{
|
Text = "TOP10不良统计",
|
TextSize = 20,
|
Paint = new SolidColorPaint(new SKColor(0, 0, 0))
|
{
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
Padding = new LiveChartsCore.Drawing.Padding(15)
|
};
|
|
public ISeries[] Chart3_series { get; set; } = new ISeries[]
|
{
|
new RowSeries<SimpleData> {
|
Values = new SimpleData[]{},
|
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Left,
|
DataLabelsFormatter =
|
point => $"{point.Model.Name}",
|
|
DataLabelsSize = 15,
|
DataLabelsPadding = new Padding(30,0,0,0),
|
DataLabelsTranslate = new LvcPoint(1, 0),
|
// DataLabelsTranslate = new LvcPoint(-1, 0),
|
DataLabelsPaint = new SolidColorPaint(new SKColor(255,0,0)){
|
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
|
},
|
YToolTipLabelFormatter = point => $"{point.Model.Name} {point.Model.Value}"
|
},
|
};
|
|
public ObservableCollection<Axis> chart3_yAxes = new ObservableCollection<Axis> {
|
new Axis
|
{
|
IsVisible = false
|
}
|
};
|
public ObservableCollection<Axis> Chart3_yAxes
|
{
|
get => chart3_yAxes;
|
set
|
{
|
Set(ref chart3_yAxes, value);
|
}
|
}
|
|
private ObservableCollection<ICartesianAxis> chart3_xAxes = new ObservableCollection<ICartesianAxis> {
|
new Axis { SeparatorsPaint = new SolidColorPaint(new SKColor(220, 220, 220)) }
|
};
|
|
public ObservableCollection<ICartesianAxis> Chart3_xAxes
|
{
|
get => chart3_xAxes;
|
set
|
{
|
Set(ref chart3_xAxes, value);
|
}
|
}
|
|
#endregion
|
|
|
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 string iniFile;
|
private string DataFolder;
|
public override void InitFinish()
|
{
|
chart2.Legend = new CustomLegend();
|
iniFile = Path.Combine(BaseFolder, "Config.ini");
|
if (!File.Exists(iniFile))
|
{
|
File.Create(iniFile);
|
}
|
DataFolder = ParamSetting.DataLogFolder;
|
LoadProduct();
|
}
|
|
private void PluginControl_Loaded(object sender, RoutedEventArgs e)
|
{
|
cb0.SelectedIndex = 0;
|
cb1.SelectedIndex = 0;
|
cb2.SelectedIndex = 0;
|
cb3.SelectedIndex = 0;
|
}
|
|
private void LoadProduct()
|
{
|
List<ProductData> products = ProductManager.GetProducts<List<ProductData>>()
|
?? new List<ProductData>();
|
this.modelSelect.Items.Clear();
|
List<string> productSource = new List<string>();
|
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 string[] GetDbFiles(DateTime startTime, DateTime endTime)
|
{
|
if (!Directory.Exists(DataFolder))
|
{
|
return new string[0];
|
}
|
string startName = $"Data_{startTime.ToString("yyyyMMdd")}";
|
string endName = $"Data_{endTime.ToString("yyyyMMdd")}";
|
var oldFiles = Directory.GetFiles(DataFolder, "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(string model, DateTime start, DateTime end)
|
{
|
var s1 = DateTime.Now;
|
string[] files = GetDbFiles(start, end);
|
if (files == null || files.Length <= 0)
|
{
|
return new List<SerialData>();
|
}
|
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<SerialData>(dt);
|
log.Info($"Bean Cast: {(DateTime.Now - s2).TotalMilliseconds}");
|
return data;
|
}
|
|
private List<SerialData> SelectResultDataByTime(string model, DateTime start, DateTime end)
|
{
|
string[] files = GetDbFiles(start, end);
|
if (files == null || files.Length <= 0)
|
{
|
return new List<SerialData>();
|
}
|
|
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} Order BY id DESC;";
|
|
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.EnsureCoreWebView2Async();
|
// 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;
|
string model = modelSelect.SelectedItem?.ToString();
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
// webview2.CoreWebView2?.ExecuteScriptAsync($"loading0('加载中,请稍后...')");
|
}));
|
List<SerialData> datas = SelectResultDataByTime(model, 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(() =>
|
{
|
Chart0_series[0].Values = new int[] { all, output };
|
//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<SerialData> datas = SelectResultDataByTime(model, 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(() =>
|
{
|
Chart1_series[0].Values = new int[] { pieData["Passed"] };
|
Chart1_series[1].Values = new int[] { pieData["Failed"] };
|
// 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;
|
string model = modelSelect.SelectedItem?.ToString();
|
Task.Run(() =>
|
{
|
try
|
{
|
Dispatcher.BeginInvoke(new Action(() =>
|
{
|
// webview2.CoreWebView2?.ExecuteScriptAsync($"loading2('加载中,请稍后...')");
|
}));
|
List<SerialData> datas = SelectResultDataByTime(model, 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(() =>
|
{
|
if (res.Count == 0)
|
{
|
res[DateTime.Now.ToString("yyyy-MM-dd")] = new PassRateData
|
{
|
onePassRate = 0,
|
passRate = 0
|
};
|
}
|
|
string[] keys = new string[res.Count];
|
double[] val0 = new double[res.Count];
|
double[] val1 = new double[res.Count];
|
int i = 0;
|
foreach (var key in res.Keys)
|
{
|
keys[i] = key;
|
val0[i] = res[key].onePassRate;
|
val1[i] = res[key].passRate;
|
i++;
|
}
|
Chart2_xAxes[0] = new Axis
|
{
|
Labels = keys,
|
};
|
Chart2_series[0].Values = val0;
|
Chart2_series[1].Values = val1;
|
//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<SerialData> datas = SelectSerialDataByTime(model, 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(() =>
|
{
|
Chart3_series[0].Values = datasource.OrderBy(x => x.Value).ToList(); ;
|
//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);
|
}
|
}
|
}
|
}
|