729 lines
27 KiB
C#
729 lines
27 KiB
C#
using MECF.Framework.Common.DataCenter;
|
||
using MECF.Framework.UI.Client.ClientBase;
|
||
using SciChart.Charting.Common.Helpers;
|
||
using SciChart.Charting.ViewportManagers;
|
||
using SciChart.Charting.Visuals.Annotations;
|
||
using SciChart.Charting.Visuals.Axes;
|
||
using SciChart.Charting.Visuals.RenderableSeries;
|
||
using SciChart.Data.Model;
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Data;
|
||
using System.Windows;
|
||
using Cali = Caliburn.Micro;
|
||
using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory;
|
||
using System.Reflection;
|
||
using SciChart.Charting.Model.ChartSeries;
|
||
using System.IO;
|
||
|
||
namespace SicUI.Models.PMs.Charting
|
||
{
|
||
public class PMChartingV2ViewModel : SicModuleUIViewModelBase, ISupportMultipleSystem
|
||
{
|
||
private class QueryIndexer
|
||
{
|
||
public DateTime StartTime { get; set; }
|
||
public DateTime EndTime { get; set; }
|
||
public string Module { get; set; }
|
||
public string ColumneName { get; set; }
|
||
public string ProcessGuid { get; set; }
|
||
public List<string> DateList { get; set; }
|
||
public long currentTimeTicks { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// ViewModel绑定的View对象
|
||
/// </summary>
|
||
private PMChartingV2View view;
|
||
|
||
/// <summary>
|
||
/// 初始化界面
|
||
/// </summary>
|
||
public PMChartingV2ViewModel()
|
||
{
|
||
DisplayName = "Process History";
|
||
|
||
var now = DateTime.Now;
|
||
this.StartDateTime = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0, 0);
|
||
this.EndDateTime = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59, 999);
|
||
|
||
SourcePM = new ObservableCollection<string>(new[] { "PM1", "PM2" });
|
||
|
||
//sci按钮操作
|
||
DataDetailVisbleCommand = new ActionCommand(SetDataDetailVisble);
|
||
DefaultZoomCommand = new ActionCommand(Zoom);
|
||
ShowLegendCommand = new ActionCommand(SetLegendAvalible);
|
||
|
||
//获取所有Device
|
||
GetPMNode();
|
||
|
||
SelectedData = new ObservableCollection<IRenderableSeriesViewModel>();
|
||
|
||
SelectedRecipes = new ObservableCollection<RecipeItemSic>();
|
||
Recipes = new ObservableCollection<RecipeItemSic>();
|
||
|
||
//x y always指zoom功能失效,总是自动调整大小
|
||
//ChartAutoRange = AutoRange.Always;
|
||
|
||
VisibleRangeX = new DoubleRange(-1000, 10000);
|
||
VisibleRangeY = new DoubleRange(-10, 500);
|
||
VisibleRangeXLimit = new DoubleRange(-1000, 10000);
|
||
VisibleRangeYLimit = new DoubleRange(-10, 500);
|
||
|
||
_thread = new PeriodicJob(300, MonitorHistoryData, "History", true);
|
||
//_threadReal = new PeriodicJob(TrendInterval, MonitorRealTimeData, "RealTime", true);
|
||
}
|
||
|
||
protected override void OnViewLoaded(object _view)
|
||
{
|
||
//获取绑定的View(wpf没有默认的日期时间控件,Winform日期控件无法通过绑定属性获取)
|
||
base.OnViewLoaded(_view);
|
||
this.view = (PMChartingV2View)_view;
|
||
this.view.wfTimeFrom.Value = this.StartDateTime;
|
||
this.view.wfTimeTo.Value = this.EndDateTime;
|
||
|
||
}
|
||
|
||
private PeriodicJob _thread;
|
||
//private PeriodicJob _threadReal;
|
||
//DeviceTimer dt = new DeviceTimer();
|
||
|
||
//设置允许同时显示的最多曲线数
|
||
private const int MAX_PARAMETERS = 20;
|
||
|
||
/// <summary>
|
||
/// sci图表的视图管理类
|
||
/// </summary>
|
||
private readonly IViewportManager _viewportManager = new DefaultViewportManager();
|
||
public IViewportManager ViewportManager
|
||
{
|
||
get { return _viewportManager; }
|
||
}
|
||
|
||
#region Properties
|
||
|
||
/// <summary>
|
||
/// 搜索条件:Recipe开始时间
|
||
/// </summary>
|
||
public DateTime StartDateTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 搜索条件:Recipe结束时间
|
||
/// </summary>
|
||
public DateTime EndDateTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 搜索条件:PM腔
|
||
/// </summary>
|
||
public string SelectedValuePM { get; set; }
|
||
|
||
/// <summary>
|
||
/// 搜索条件:PM腔
|
||
/// </summary>
|
||
public ObservableCollection<string> SourcePM { get; set; }
|
||
/// <summary>
|
||
/// 搜索条件:Recipe
|
||
/// </summary>
|
||
public string RecipeName { get; set; }
|
||
|
||
/// <summary>
|
||
/// 查询曲线用点位组,每次有曲线变动时入队,生成曲线后出队
|
||
/// </summary>
|
||
ConcurrentBag<QueryIndexer> _lstTokenTimeData = new ConcurrentBag<QueryIndexer>();
|
||
|
||
public ObservableCollection<DataDetail> QueryDataDetail { get; set; }
|
||
|
||
/// <summary>
|
||
/// 用户选中的曲线组,前台treeview和chart调用
|
||
/// </summary>
|
||
public ObservableCollection<IRenderableSeriesViewModel> SelectedData { get; set; }
|
||
|
||
/// <summary>
|
||
/// 根据条件搜索的recipe
|
||
/// </summary>
|
||
public ObservableCollection<RecipeItemSic> Recipes { get; set; }
|
||
|
||
/// <summary>
|
||
/// 用户选中查阅的recipe
|
||
/// </summary>
|
||
public ObservableCollection<RecipeItemSic> SelectedRecipes { get; set; }
|
||
|
||
|
||
private List<PMNodeInfo> Nodes = new List<PMNodeInfo>();
|
||
/// <summary>
|
||
/// 获取设备需要监控的Device点
|
||
/// </summary>
|
||
private ObservableCollection<PMNodeInfo> _configNodes = new ObservableCollection<PMNodeInfo>();
|
||
public ObservableCollection<PMNodeInfo> ConfigNodes
|
||
{
|
||
get { return _configNodes; }
|
||
set { _configNodes = value; NotifyOfPropertyChange("ConfigNodes"); }
|
||
}
|
||
|
||
private double _maxYValue = 0, _minYValue = 0;
|
||
|
||
private IRange _visibleRangeXLimit;
|
||
public IRange VisibleRangeXLimit
|
||
{
|
||
get { return _visibleRangeXLimit;}
|
||
set { _visibleRangeXLimit = value; NotifyOfPropertyChange(nameof(VisibleRangeXLimit)); }
|
||
}
|
||
|
||
private IRange _visibleRangeYLimit;
|
||
public IRange VisibleRangeYLimit
|
||
{
|
||
get { return _visibleRangeYLimit; }
|
||
set { _visibleRangeYLimit = value; NotifyOfPropertyChange(nameof(VisibleRangeYLimit)); }
|
||
}
|
||
|
||
private IRange _visibleRangeX;
|
||
public IRange VisibleRangeX
|
||
{
|
||
get { return _visibleRangeX; }
|
||
set { _visibleRangeX = value; NotifyOfPropertyChange(nameof(VisibleRangeX)); }
|
||
}
|
||
private IRange _visibleRangeY;
|
||
public IRange VisibleRangeY
|
||
{
|
||
get { return _visibleRangeY; }
|
||
set { _visibleRangeY = value; NotifyOfPropertyChange(nameof(VisibleRangeY)); }
|
||
}
|
||
|
||
private AutoRange _chartAutoRange = AutoRange.Never;
|
||
public AutoRange ChartAutoRange
|
||
{
|
||
get { return _chartAutoRange; }
|
||
set
|
||
{
|
||
_chartAutoRange = value;
|
||
NotifyOfPropertyChange(nameof(ChartAutoRange));
|
||
}
|
||
}
|
||
|
||
private Visibility _dataDetailVisbility = Visibility.Collapsed;
|
||
public Visibility DataDetailVisbility
|
||
{
|
||
get { return _dataDetailVisbility; }
|
||
set
|
||
{
|
||
_dataDetailVisbility = value;
|
||
NotifyOfPropertyChange(nameof(DataDetailVisbility));
|
||
}
|
||
}
|
||
|
||
private bool _showLegendInfo;
|
||
public bool ShowLegendInfo
|
||
{
|
||
get { return _showLegendInfo; }
|
||
set
|
||
{
|
||
_showLegendInfo = value;
|
||
NotifyOfPropertyChange(nameof(ShowLegendInfo));
|
||
}
|
||
}
|
||
|
||
private Queue<Color> colorQueue = new Queue<Color>(new Color[]{Color.Red,Color.Orange,Color.Green,Color.Blue,Color.Purple,Color.Aqua,Color.Bisque,Color.Brown,Color.BurlyWood,Color.CadetBlue,
|
||
Color.CornflowerBlue,Color.DarkBlue,Color.DarkCyan,Color.DarkGray,Color.DarkGreen,Color.DarkKhaki,Color.DarkMagenta,Color.DarkOliveGreen, Color.DarkOrange,
|
||
Color.DarkSeaGreen,Color.DarkSlateBlue,Color.DarkSlateGray,Color.DarkViolet,Color.DeepPink,Color.DeepSkyBlue,Color.DimGray, Color.DodgerBlue,Color.ForestGreen, Color.Gold,
|
||
Color.Gray,Color.GreenYellow,Color.HotPink,Color.Indigo,Color.Khaki,
|
||
Color.LimeGreen,Color.MediumOrchid,Color.MediumPurple,Color.MediumSeaGreen,Color.MediumSlateBlue,Color.MediumSpringGreen,
|
||
Color.MediumTurquoise,Color.Moccasin,Color.NavajoWhite,Color.Olive,Color.OliveDrab,Color.OrangeRed,Color.Orchid,Color.PaleGoldenrod,Color.PaleGreen,
|
||
Color.PeachPuff,Color.Peru,Color.Plum,Color.PowderBlue,Color.RosyBrown,Color.RoyalBlue,Color.SaddleBrown,Color.Salmon,Color.SeaGreen, Color.Sienna,
|
||
Color.SkyBlue,Color.SlateBlue,Color.SlateGray,Color.SpringGreen,Color.Teal,Color.Aquamarine,Color.Tomato,Color.Turquoise,Color.Violet,Color.Wheat, Color.YellowGreen});
|
||
|
||
#endregion Properties
|
||
|
||
|
||
#region 界面按钮
|
||
|
||
|
||
/// <summary>
|
||
/// 重新搜索Recipe
|
||
/// </summary>
|
||
public void SearchRecipe()
|
||
{
|
||
this.StartDateTime = this.view.wfTimeFrom.Value;
|
||
this.EndDateTime = this.view.wfTimeTo.Value;
|
||
|
||
if (StartDateTime > EndDateTime)
|
||
{
|
||
MessageBox.Show("Time range invalid, start time should be early than end time");
|
||
return;
|
||
}
|
||
|
||
Recipes.Clear();
|
||
RemoveAllLine();
|
||
|
||
try
|
||
{
|
||
string sql = $"SELECT * FROM \"process_data\" where \"process_data\".\"process_begin_time\" >='{StartDateTime:yyyyMMdd HHmmss}' and \"process_data\".\"process_end_time\" <='{EndDateTime:yyyyMMdd HHmmss}'";
|
||
if (!string.IsNullOrEmpty(SelectedValuePM))
|
||
{
|
||
string[] pms = SelectedValuePM.Split(',');
|
||
if (pms.Length > 0)
|
||
{
|
||
sql += " and (FALSE ";
|
||
foreach (var pm in pms)
|
||
{
|
||
sql += $" OR \"process_data\".\"process_in\"='{pm}' ";
|
||
}
|
||
sql += " ) ";
|
||
}
|
||
}
|
||
|
||
if (!string.IsNullOrEmpty(RecipeName))
|
||
{
|
||
sql += string.Format(" and lower( \"process_data\".\"recipe_name\") like '%{0}%'", RecipeName.ToLower());
|
||
}
|
||
|
||
sql += " order by \"process_data\".\"process_begin_time\" ASC;";
|
||
|
||
DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
|
||
|
||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||
{
|
||
if (dbData == null || dbData.Rows.Count == 0)
|
||
return;
|
||
|
||
double maxXValue = 0;
|
||
|
||
for (int i = 0; i < dbData.Rows.Count; i++)
|
||
{
|
||
RecipeItemSic item = new RecipeItemSic();
|
||
|
||
item.Recipe = dbData.Rows[i]["recipe_name"].ToString();
|
||
item.Chamber = dbData.Rows[i]["process_in"].ToString();
|
||
item.Status = dbData.Rows[i]["process_status"].ToString();
|
||
//item.ProcessGuid = dbData.Rows[i]["guid"].ToString();
|
||
item.ProcessGuid = "Recipe"+i.ToString().PadLeft(3,'0');
|
||
|
||
if (!dbData.Rows[i]["process_begin_time"].Equals(DBNull.Value))
|
||
item.StartTime = ((DateTime)dbData.Rows[i]["process_begin_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
|
||
if (!dbData.Rows[i]["process_end_time"].Equals(DBNull.Value))
|
||
item.EndTime = ((DateTime)dbData.Rows[i]["process_end_time"]).ToString("yyyy/MM/dd HH:mm:ss.fff");
|
||
|
||
long curTickCount = (DateTime.Parse(item.EndTime).Ticks - DateTime.Parse(item.StartTime).Ticks) / 10000000;
|
||
if (maxXValue < curTickCount)
|
||
{
|
||
maxXValue = curTickCount;
|
||
}
|
||
//正确设置范围,否则曲线不显示
|
||
VisibleRangeX = new DoubleRange(-0.2*maxXValue, maxXValue * 1.2);
|
||
VisibleRangeXLimit = new DoubleRange(-0.2 * maxXValue, maxXValue * 1.2);//X轴拉伸1.2倍
|
||
|
||
Recipes.Add(item);
|
||
}
|
||
}));
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
LOG.Write(e);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 选择Recipe
|
||
/// </summary>
|
||
public void CheckRecipe(RecipeItemSic recipe)
|
||
{
|
||
if (recipe.Selected) //选中配方
|
||
{
|
||
SelectedRecipes.Add(recipe);
|
||
//刷新曲线
|
||
//GetXRange();
|
||
foreach (PMNodeInfo node in ConfigNodes)
|
||
{
|
||
if (node.Selected)
|
||
{
|
||
ParameterCheck(node);
|
||
}
|
||
}
|
||
}
|
||
else //取消配方
|
||
{
|
||
RecipeItemSic item = SelectedRecipes.FirstOrDefault(t => t.Recipe == recipe.Recipe);
|
||
if (item != null)
|
||
SelectedRecipes.Remove(item);
|
||
RemoveRecipeRelated(recipe); //移除配方相关曲线
|
||
}
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 移除配方相关曲线
|
||
/// </summary>
|
||
/// <param name="recipe"></param>
|
||
private void RemoveRecipeRelated(RecipeItemSic recipe)
|
||
{
|
||
lock (_lockSelection) //递减法移除列表内项,不会删错
|
||
{
|
||
for (int i = SelectedData.Count - 1; i >= 0; i--)
|
||
{
|
||
if ((SelectedData[i] as ChartDataLineXV2).ProcessGuid.Contains(recipe.ProcessGuid))
|
||
{
|
||
SelectedData.RemoveAt(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除所有选择的节点
|
||
/// </summary>
|
||
public void RemoveAllLine()
|
||
{
|
||
this.SelectedData.Clear();
|
||
foreach (PMNodeInfo node in ConfigNodes)
|
||
{
|
||
node.Selected = false;
|
||
}
|
||
}
|
||
|
||
#endregion 界面按钮
|
||
|
||
private void SelectedDataChanged()
|
||
{
|
||
foreach (var item in SelectedData)
|
||
{
|
||
if (item.Stroke.Equals(System.Windows.Media.Color.FromArgb(255, 0, 0, 255)))
|
||
{
|
||
Color drawingColor = colorQueue.Peek();
|
||
item.Stroke = System.Windows.Media.Color.FromRgb(drawingColor.R, drawingColor.G, drawingColor.B);
|
||
colorQueue.Enqueue(colorQueue.Dequeue());
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载PM的Device名称
|
||
/// </summary>
|
||
private void GetPMNode()
|
||
{
|
||
Nodes.Clear();
|
||
ConfigNodes.Clear();
|
||
List<string> dataList = (List<string>)QueryDataClient.Instance.Service.GetConfig("System.NumericDataList");
|
||
dataList.Sort();
|
||
List<string> lstNode = new List<string>();
|
||
foreach (string dataName in dataList)
|
||
{
|
||
string[] nodeName = dataName.Split('.');
|
||
if (nodeName.Length > 1 && nodeName[0].IndexOf("PM") == 0)
|
||
{
|
||
string nodeStr = dataName.Substring(dataName.IndexOf('.') + 1);
|
||
if (!lstNode.Contains(nodeStr)) //不显示重复项
|
||
{
|
||
lstNode.Add(nodeStr);
|
||
Nodes.Add(new PMNodeInfo() { NodeStr = nodeStr });
|
||
ConfigNodes.Add(new PMNodeInfo() { NodeStr = nodeStr });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public void Find(string keyword)
|
||
{
|
||
ConfigNodes.Clear();
|
||
//遍历所有node,隐藏不符合条件项
|
||
foreach (var node in Nodes)
|
||
{
|
||
node.ApplyCriteria(keyword);
|
||
if (node.IsMatch)
|
||
{
|
||
ConfigNodes.Add(node);
|
||
}
|
||
}
|
||
}
|
||
private void SetDataDetailVisble()
|
||
{
|
||
if (DataDetailVisbility == Visibility.Collapsed)
|
||
{
|
||
DataDetailVisbility = Visibility.Visible;
|
||
}
|
||
else
|
||
{
|
||
DataDetailVisbility = Visibility.Collapsed;
|
||
}
|
||
}
|
||
|
||
#region 获取HistoryData
|
||
|
||
private object _lockSelection = new object();
|
||
|
||
protected bool MonitorHistoryData()
|
||
{
|
||
try
|
||
{
|
||
if (_lstTokenTimeData.Count > 0)
|
||
{
|
||
lock (_lockSelection)
|
||
{
|
||
foreach (var item in _lstTokenTimeData)
|
||
{
|
||
DateTime timeFrom = item.StartTime;
|
||
DateTime timeTo = item.EndTime;
|
||
|
||
GetHistoryData(item.DateList, timeFrom, timeTo, item.Module, item.ColumneName, item.ProcessGuid);
|
||
_lstTokenTimeData.TryTake(out _);
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LOG.Error(ex.Message);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
private void GetHistoryData(List<string> lstDayStr, DateTime from, DateTime to, string module, string colName, string processGuid)
|
||
{
|
||
Dictionary<string, List<DataDetail>> historyData = new Dictionary<string, List<DataDetail>>();
|
||
List<DataDetail> lstDataDetail = new List<DataDetail>();
|
||
|
||
//db获取对应字段数据
|
||
foreach (string cDate in lstDayStr)
|
||
{
|
||
string sql = String.Format("select time AS InternalTimeStamp,\"{0}\"", colName);
|
||
sql += string.Format(" from \"{0}\" where time > {1} and time <= {2} order by time asc",
|
||
cDate + "." + module, from.Ticks, to.Ticks);
|
||
|
||
DataTable dataTable = QueryDataClient.Instance.Service.QueryData(sql);
|
||
if (dataTable == null || dataTable.Rows.Count == 0 || dataTable.Columns.Count < 2)
|
||
{
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
||
{
|
||
DataDetail data = new DataDetail();
|
||
long ticks = (long)dataTable.Rows[i][0] - from.Ticks;
|
||
data.xValue = ticks / 10000000;
|
||
if (dataTable.Rows[i][1] is DBNull || dataTable.Rows[i][1] is null)
|
||
{
|
||
data.yValue = 0;
|
||
}
|
||
else if (dataTable.Rows[i][1] is bool)
|
||
{
|
||
data.yValue = (bool)dataTable.Rows[i][1] ? 1 : 0;
|
||
}
|
||
else
|
||
{
|
||
data.yValue = float.Parse(dataTable.Rows[i][1].ToString());
|
||
}
|
||
if (data.yValue > _maxYValue)
|
||
{
|
||
_maxYValue = data.yValue;
|
||
}
|
||
if (data.yValue < _minYValue)
|
||
{
|
||
_minYValue = data.yValue;
|
||
}
|
||
lstDataDetail.Add(data);
|
||
}
|
||
}
|
||
//正确设置范围,否则曲线不显示
|
||
VisibleRangeY = new DoubleRange(_minYValue - _maxYValue * 0.5, _maxYValue * 2.1);
|
||
VisibleRangeYLimit = new DoubleRange(_minYValue - _maxYValue * 0.5, _maxYValue * 2.1);//Y轴拉伸1.2倍
|
||
|
||
//所有数据内存
|
||
historyData.Add(processGuid, lstDataDetail);
|
||
|
||
//数据绑定到曲线中
|
||
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
|
||
{
|
||
try
|
||
{
|
||
foreach (var item in SelectedData)
|
||
{
|
||
var seriesItem = item as ChartDataLineXV2;
|
||
|
||
if (seriesItem == null)
|
||
continue;
|
||
foreach (var data in historyData)
|
||
{
|
||
if (data.Key != seriesItem.ProcessGuid)
|
||
continue;
|
||
|
||
seriesItem.Capacity += data.Value.Count;
|
||
|
||
foreach (var detailDataItem in data.Value)
|
||
{
|
||
seriesItem.Append(detailDataItem.xValue, detailDataItem.yValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LOG.Write(ex);
|
||
}
|
||
}));
|
||
}
|
||
#endregion
|
||
|
||
|
||
/// <summary>
|
||
/// 更新Data变化
|
||
/// </summary>
|
||
/// <param name="node"></param>
|
||
/// <returns></returns>
|
||
public bool ParameterCheck(PMNodeInfo node)
|
||
{
|
||
if (SelectedRecipes.Count == 0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (node.Selected)
|
||
{
|
||
foreach (RecipeItemSic itemSic in SelectedRecipes)
|
||
{
|
||
string nodeStr = itemSic.Chamber + "." + node.NodeStr; //字段名称
|
||
string nodeStr_1 = itemSic.LotID; //显示名称
|
||
string nodeWithGuid = node.NodeStr + "_" + itemSic.ProcessGuid; //字段名+ Guid (唯一ID)
|
||
DateTime dtStartTime = DateTime.Parse(itemSic.StartTime);
|
||
DateTime dtEndTime = DateTime.Parse(itemSic.EndTime);
|
||
|
||
lock (_lockSelection)
|
||
{
|
||
bool isExist = SelectedData.FirstOrDefault(x => (x as ChartDataLineXV2).ProcessGuid == nodeWithGuid) != null;
|
||
if (!isExist)
|
||
{
|
||
if (SelectedData.Count < MAX_PARAMETERS)
|
||
{
|
||
var line = new ChartDataLineXV2(nodeWithGuid);
|
||
line.Time=itemSic.StartTime+"-"+itemSic.EndTime;
|
||
line.RecipeName = new DirectoryInfo(itemSic.Recipe).Name;
|
||
if (itemSic.Chamber.StartsWith("PM1"))
|
||
line.Module = "PM1";
|
||
else if (itemSic.Chamber.StartsWith("PM2"))
|
||
line.Module = "PM2";
|
||
else
|
||
line.Module = "System";
|
||
line.ProcessGuid = nodeWithGuid;
|
||
line.RecName = nodeStr_1;
|
||
line.Tag = node;
|
||
line.Append(0, 0);
|
||
SelectedData.Add(line);
|
||
SelectedDataChanged();
|
||
QueryIndexer indexer = _lstTokenTimeData.FirstOrDefault(x => x.ProcessGuid == line.ProcessGuid);
|
||
|
||
if (indexer == null)
|
||
{
|
||
indexer = new QueryIndexer()
|
||
{
|
||
Module = line.Module,
|
||
StartTime = dtStartTime,
|
||
EndTime = dtEndTime,
|
||
ProcessGuid = line.ProcessGuid,
|
||
ColumneName = nodeStr,
|
||
DateList = GetDateList(dtStartTime, dtEndTime)
|
||
};
|
||
|
||
_lstTokenTimeData.Add(indexer);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
lock (_lockSelection)
|
||
{
|
||
for (int i = SelectedData.Count - 1; i >= 0; i--)
|
||
{
|
||
if ((SelectedData[i] as ChartDataLineXV2).DataName.Contains(node.NodeStr))
|
||
{
|
||
SelectedData.RemoveAt(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public void SelectColor(ChartDataLineXV2 cp)
|
||
{
|
||
if (cp == null)
|
||
return;
|
||
|
||
var dlg = new System.Windows.Forms.ColorDialog();
|
||
if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||
{
|
||
cp.Stroke = new System.Windows.Media.Color() { A = dlg.Color.A, B = dlg.Color.B, G = dlg.Color.G, R = dlg.Color.R };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取开始时间和结束时间之间的所有日期
|
||
/// </summary>
|
||
/// <param name="timeStart"></param>
|
||
/// <param name="timeEnd"></param>
|
||
/// <returns></returns>
|
||
private List<string> GetDateList(DateTime timeStart, DateTime timeEnd)
|
||
{
|
||
List<string> lstTime = new List<string>();
|
||
string dtEndStr = timeEnd.ToString("yyyyMMdd");
|
||
int timeSpan = (int)(timeEnd - timeStart).TotalDays + 1;
|
||
for (int i = 0; i <= timeSpan; i++)
|
||
{
|
||
string dt = timeStart.AddDays(i).ToString("yyyyMMdd");
|
||
lstTime.Add(dt);
|
||
if (dt == dtEndStr)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
return lstTime;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有的列名
|
||
/// </summary>
|
||
private List<string> GetColumnList(string modleName)
|
||
{
|
||
List<string> _seletedItemName = new List<string>();
|
||
foreach (PMNodeInfo node in ConfigNodes)
|
||
{
|
||
if (node.Selected)
|
||
{
|
||
_seletedItemName.Add("\"" + modleName + "." + node.NodeStr + "\"");
|
||
}
|
||
}
|
||
return _seletedItemName;
|
||
}
|
||
|
||
public ActionCommand DefaultZoomCommand { get; private set; }
|
||
public ActionCommand ShowLegendCommand { get; private set; }
|
||
public ActionCommand DataDetailVisbleCommand { get; private set; }
|
||
public ActionCommand ShowAlarmCommand { get; private set; }
|
||
|
||
|
||
private void SetLegendAvalible()
|
||
{
|
||
ShowLegendInfo = !ShowLegendInfo;
|
||
}
|
||
|
||
private void Zoom()
|
||
{
|
||
ViewportManager.AnimateZoomExtents(TimeSpan.FromMilliseconds(500));
|
||
}
|
||
|
||
}
|
||
}
|