2023-06-29 12:10:20 +08:00
using Aitex.Core.UI.ControlDataContext ;
2023-03-03 15:42:13 +08:00
using Caliburn.Micro.Core ;
using MECF.Framework.Common.ControlDataContext ;
using MECF.Framework.Common.DataCenter ;
using MECF.Framework.UI.Client.CenterViews.DataLogs.ProcessHistory ;
using MECF.Framework.UI.Client.ClientBase ;
using SciChart.Charting.ChartModifiers ;
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.Diagnostics ;
using System.Drawing ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
using System.Windows ;
using System.Windows.Data ;
using Cali = Caliburn . Micro ;
namespace SicUI.Models.PMs.Charting
{
public class RecipeItemSic : RecipeItem
{
public string SyncStep { get ; set ; }
public string ProcessGuid { get ; set ; }
}
[Serializable]
public class PMNodeInfo : PropertyChangedBase
{
private bool _selected = false ;
public bool Selected
{
get { return _selected ; }
set
{
_selected = value ;
NotifyOfPropertyChange ( "Selected" ) ;
}
}
public string NodeStr { get ; set ; }
private bool _isMatch = true ;
public bool IsMatch
{
get { return _isMatch ; }
set { _isMatch = value ; NotifyOfPropertyChange ( "IsMatch" ) ; }
}
public void ApplyCriteria ( string criteria )
{
if ( IsCriteriaMatched ( criteria ) )
{
IsMatch = true ;
}
else
{
IsMatch = false ;
}
}
private bool IsCriteriaMatched ( string criteria )
{
return ! string . IsNullOrEmpty ( criteria ) & & NodeStr . ToLower ( ) . Contains ( criteria . ToLower ( ) ) | | string . IsNullOrEmpty ( criteria ) ;
}
}
public class DataDetail
{
public string ProcessGuid { get ; set ; }
public double xValue { get ; set ; }
public double yValue { get ; set ; }
}
public class PMChartingViewModel : 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 ; }
}
public PMChartingViewModel ( )
{
DisplayName = "Process History" ;
DataDetailVisbleCommand = new ActionCommand ( SetDataDetailVisble ) ;
DefaultZoomCommand = new ActionCommand ( Zoom ) ;
ShowLegendCommand = new ActionCommand ( SetLegendAvalible ) ;
ShowAlarmCommand = new ActionCommand ( AddAlarmInfo ) ;
GetPMNode ( ) ;
SelectedData = new ObservableCollection < IRenderableSeries > ( ) ;
Recipes = new ObservableCollection < RecipeItemSic > ( ) ;
AutoRangeX = AutoRange . Always ;
AutoRangeY = AutoRange . Always ;
VisibleRangeX = new DoubleRange ( 0 , 10000 ) ;
VisibleRangeY = new DoubleRange ( - 10 , 500 ) ;
VisibleRangeXLimit = new DoubleRange ( 0 , 10000 ) ;
VisibleRangeYLimit = new DoubleRange ( - 10 , 500 ) ;
AddRangeAnnotation ( ) ;
_thread = new PeriodicJob ( 200 , MonitorHistoryData , "History" , true ) ;
_threadReal = new PeriodicJob ( TrendInterval , MonitorRealTimeData , "RealTime" , true ) ;
}
private PeriodicJob _thread ;
private PeriodicJob _threadReal ;
//DeviceTimer dt = new DeviceTimer();
private const int MAX_PARAMETERS = 20 ;
public DateTime _queryDateTimeToken ;
private readonly IViewportManager _viewportManager = new DefaultViewportManager ( ) ;
public IViewportManager ViewportManager
{
get { return _viewportManager ; }
}
#region Properties
[IgnorePropertyChange]
public int TrendInterval { get ; set ; } = 5000 ;
public bool IntervalSaved { get ; set ; }
private DateTime _realTimeStart = DateTime . MaxValue ;
private string _realTimeGuid = "" ;
private long _realTimeTick = 0 ;
private List < string > _seletedItemName = new List < string > ( ) ;
ConcurrentBag < QueryIndexer > _lstTokenTimeData = new ConcurrentBag < QueryIndexer > ( ) ;
//ConcurrentBag<QueryIndexer> _lstRealTimeData = new ConcurrentBag<QueryIndexer>();
//List<string> _lstRemoveRecipe = new List<string>();
public ObservableCollection < DataDetail > QueryDataDetail { get ; set ; }
public ObservableCollection < IRenderableSeries > SelectedData { get ; set ; }
public ObservableCollection < RecipeItemSic > Recipes { get ; set ; }
private AnnotationCollection _alarmAnnotation ;
public AnnotationCollection AlarmAnnotation
{
get { return _alarmAnnotation ; }
set
{
_alarmAnnotation = value ;
NotifyOfPropertyChange ( nameof ( AlarmAnnotation ) ) ;
}
}
private RecipeItemSic _selectedProcessData ;
public RecipeItemSic SelectedProcessData
{
get { return _selectedProcessData ; }
set
{
_selectedProcessData = value ;
NotifyOfPropertyChange ( nameof ( SelectedProcessData ) ) ;
}
}
private List < PMNodeInfo > _ConfigNodes = new List < PMNodeInfo > ( ) ;
public List < PMNodeInfo > ConfigNodes
{
get { return _ConfigNodes ; }
set { _ConfigNodes = value ; NotifyOfPropertyChange ( "ConfigNodes" ) ; }
}
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 ) ) ; }
}
public string UseSetX1
{
get ; set ;
}
public string UseSetX2
{
get ; set ;
}
public string UseSetY1
{
get ; set ;
}
public string UseSetY2
{
get ; set ;
}
private AutoRange _autoRangeX ;
public AutoRange AutoRangeX
{
get = > _autoRangeX ;
set { _autoRangeX = value ; NotifyOfPropertyChange ( nameof ( AutoRangeX ) ) ; }
}
private AutoRange _autoRangeY ;
public AutoRange AutoRangeY
{
get = > _autoRangeY ;
set { _autoRangeY = value ; NotifyOfPropertyChange ( nameof ( AutoRangeY ) ) ; }
}
private bool _enableAutoZoom = true ;
public bool EnableAutoZoom
{
get { return _enableAutoZoom ; }
set
{
_enableAutoZoom = value ;
NotifyOfPropertyChange ( nameof ( EnableAutoZoom ) ) ;
NotifyOfPropertyChange ( nameof ( ChartAutoRange ) ) ;
}
}
private AutoRange _chartAutoRange = AutoRange . Never ;
public AutoRange ChartAutoRange
{
get { return _chartAutoRange ; }
set
{
_chartAutoRange = value ;
NotifyOfPropertyChange ( nameof ( ChartAutoRange ) ) ;
}
}
private bool _realTimeMode ;
public bool RealTimeMode
{
get { return _realTimeMode ; }
set
{
_realTimeMode = value ;
NotifyOfPropertyChange ( nameof ( RealTimeMode ) ) ;
if ( _realTimeMode )
{
AddRealTimeInfo ( ) ;
}
else
{
ClearRealTimeInfo ( ) ;
}
}
}
private string _currentCriteria = String . Empty ;
public string CurrentCriteria
{
get { return _currentCriteria ; }
set
{
if ( value = = _currentCriteria )
return ;
_currentCriteria = value ;
NotifyOfPropertyChange ( "CurrentCriteria" ) ;
ApplyFilter ( ) ;
}
}
private double _realTimeX ;
public double RealTimeX
{
get { return _realTimeX ; }
set
{
_realTimeX = value ;
NotifyOfPropertyChange ( nameof ( RealTimeX ) ) ;
}
}
private double _thresholdX1 ;
public double ThresholdX1
{
get { return _thresholdX1 ; }
set
{
_thresholdX1 = value ;
NotifyOfPropertyChange ( nameof ( ThresholdX1 ) ) ;
}
}
private double _thresholdX2 ;
public double ThresholdX2
{
get { return _thresholdX2 ; }
set
{
_thresholdX2 = value ;
NotifyOfPropertyChange ( nameof ( ThresholdX2 ) ) ;
}
}
private bool _showLegendInfo ;
public bool ShowLegendInfo
{
get { return _showLegendInfo ; }
set
{
_showLegendInfo = value ;
NotifyOfPropertyChange ( nameof ( ShowLegendInfo ) ) ;
}
}
private Visibility _dataDetailVisbility = Visibility . Collapsed ;
public Visibility DataDetailVisbility
{
get { return _dataDetailVisbility ; }
set
{
_dataDetailVisbility = value ;
NotifyOfPropertyChange ( nameof ( DataDetailVisbility ) ) ;
}
}
private Dictionary < string , string > keyValuesAlarm = new Dictionary < string , string > ( ) ;
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
Cali . WindowManager wm = new Cali . WindowManager ( ) ;
ChartingSelectDataViewModel selectDataDlg = new ChartingSelectDataViewModel ( ) ;
#region 界 面 按 钮
public void Add ( )
{
selectDataDlg . CheckAllRecipeFlag = false ;
selectDataDlg . SelectedRecipes . Clear ( ) ;
selectDataDlg . SelectedParameters . Clear ( ) ;
var settings = new Dictionary < string , object > { { "Title" , "Select Recipe Data" } } ;
bool? ret = wm . ShowDialog ( selectDataDlg , null , settings ) ;
if ( ret = = null | | ! ret . Value )
return ;
for ( int j = SelectedData . Count - 1 ; j > = 0 ; j - - )
{
if ( ! ( SelectedData [ j ] as ChartDataLineX ) . RecName . Contains ( "RealTime" ) )
{
SelectedData . RemoveAt ( j ) ;
}
}
GetXRange ( ) ;
foreach ( PMNodeInfo node in ConfigNodes )
{
if ( node . Selected )
{
ParameterCheck ( node ) ;
}
}
}
/// <summary>
/// 删除所有的ProcessData信息
/// </summary>
public void RemoveAllProcessData ( )
{
Recipes . Clear ( ) ;
this . SelectedData . Clear ( ) ;
foreach ( PMNodeInfo node in ConfigNodes )
{
node . Selected = false ;
}
}
/// <summary>
/// 清除所有选择的节点
/// </summary>
public void RemoveAllLine ( )
{
this . SelectedData . Clear ( ) ;
foreach ( PMNodeInfo node in ConfigNodes )
{
node . Selected = false ;
}
}
/// <summary>
/// 删除单个ProcessData
/// </summary>
public void DeleteProcessData ( RecipeItemSic item )
{
if ( Recipes . Contains ( item ) )
{
lock ( _lockSelection )
{
for ( int j = SelectedData . Count - 1 ; j > = 0 ; j - - )
{
if ( ( SelectedData [ j ] as ChartDataLineX ) . ProcessGuid . Contains ( item . ProcessGuid ) )
{
SelectedData . RemoveAt ( j ) ;
}
}
}
this . Recipes . Remove ( item ) ;
}
}
public void Template ( )
{
ChartingTemplateViewModel templateDataDlg = new ChartingTemplateViewModel ( ) ;
templateDataDlg . CurrentDataInfo = ConfigNodes ;
Cali . WindowManager wm = new Cali . WindowManager ( ) ;
bool? bret = wm . ShowDialog ( templateDataDlg ) ;
if ( ! bret . HasValue | | ! bret . Value )
{
return ;
}
else
{
ConfigNodes = templateDataDlg . CurrentDataInfo ;
if ( SelectedData . Count > 0 )
{
lock ( _lockSelection )
{
foreach ( var node in ConfigNodes )
{
if ( ! node . Selected )
{
for ( int j = SelectedData . Count - 1 ; j > = 0 ; j - - )
{
if ( ! ( SelectedData [ j ] as ChartDataLineX ) . ProcessGuid . Contains ( node . NodeStr ) )
{
SelectedData . RemoveAt ( j ) ;
}
}
}
}
}
}
foreach ( var node in ConfigNodes )
{
ParameterCheck ( node ) ;
}
}
}
private void ClearRealTimeInfo ( )
{
_realTimeStart = DateTime . MaxValue ;
lock ( _lockSelection )
{
for ( int i = SelectedData . Count - 1 ; i > = 0 ; i - - )
{
if ( ( SelectedData [ i ] as ChartDataLineX ) . RecName = = "RealTime" )
{
SelectedData . RemoveAt ( i ) ;
}
}
}
}
private void GetXRange ( )
{
double maxXValue = 0 ;
foreach ( var recipe in selectDataDlg . SelectedRecipes )
{
if ( Recipes . FirstOrDefault ( x = > x . ProcessGuid = = recipe . ProcessGuid ) ! = null )
{
continue ;
}
this . Recipes . Add ( recipe ) ;
long curTickCount = ( DateTime . Parse ( recipe . EndTime ) . Ticks - DateTime . Parse ( recipe . StartTime ) . Ticks ) / 10000000 ;
if ( maxXValue < curTickCount )
{
maxXValue = curTickCount ;
}
}
VisibleRangeX = new DoubleRange ( 0 , maxXValue ) ;
VisibleRangeXLimit = new DoubleRange ( 0 , maxXValue ) ;
}
private void AddRealTimeInfo ( )
{
_realTimeStart = DateTime . MaxValue ;
string sqlStr = String . Format ( "SELECT \"process_data\".\"process_begin_time\",\"process_data\".\"guid\" ,\"process_data\".\"process_in\" " +
"FROM \"process_data\",\"cj_data\",\"pj_data\",\"wafer_data\" where \"process_data\".\"wafer_data_guid\" = \"wafer_data\".\"guid\" " +
"and \"wafer_data\".\"pj_data_guid\" = \"pj_data\".\"guid\" and \"cj_data\".\"guid\" = \"pj_data\".\"cj_data_guid\" " +
"and \"process_data\".\"process_begin_time\" >= '{0}' and \"process_data\".\"process_end_time\" is null " +
"order by \"process_data\".\"process_begin_time\" DESC" , DateTime . Now . AddHours ( - 3 ) . ToString ( "yyyy-MM-dd HH:mm:ss" ) ) ;
DataTable dataTable = QueryDataClient . Instance . Service . QueryData ( sqlStr ) ;
if ( dataTable ! = null & & dataTable . Rows . Count > 0 )
{
_realTimeStart = ( DateTime ) dataTable . Rows [ 0 ] [ "process_begin_time" ] ;
_realTimeGuid = dataTable . Rows [ 0 ] [ "guid" ] . ToString ( ) ;
string _realTimeChamber = dataTable . Rows [ 0 ] [ "process_in" ] . ToString ( ) ;
DateTime _realHisEndTime = DateTime . Now ;
_realTimeTick = _realHisEndTime . Ticks + 1 ;
lock ( _lockSelection )
{
foreach ( PMNodeInfo node in ConfigNodes )
{
if ( node . Selected )
{
string nodeStr = _realTimeChamber + "." + node . NodeStr ; //字段名称
string nodeWithGuid = node . NodeStr + "_" + _realTimeGuid ;
bool isExist = SelectedData . FirstOrDefault ( x = > ( x as ChartDataLineX ) . ProcessGuid = = nodeWithGuid ) ! = null ;
if ( ! isExist )
{
var line = new ChartDataLineX ( nodeStr ) ;
line . ProcessGuid = nodeWithGuid ;
line . RecName = "RealTime" ;
line . Tag = node ;
SelectedData . Add ( line ) ;
SelectedDataChanged ( ) ;
QueryIndexer indexer = _lstTokenTimeData . FirstOrDefault ( x = > x . ProcessGuid = = line . ProcessGuid ) ;
if ( indexer = = null )
{
indexer = new QueryIndexer ( )
{
Module = line . Module ,
StartTime = _realTimeStart ,
EndTime = _realHisEndTime ,
ProcessGuid = line . ProcessGuid ,
ColumneName = nodeStr ,
DateList = GetDateList ( _realTimeStart , _realHisEndTime )
} ;
_lstTokenTimeData . Add ( indexer ) ;
}
}
}
}
}
}
else
{
_realTimeStart = DateTime . MaxValue ;
}
}
#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 ( )
{
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 ) )
{
ConfigNodes . Add ( new PMNodeInfo ( ) { NodeStr = nodeStr } ) ;
}
}
}
}
private object _lockSelection = new object ( ) ;
//private object _lockRealtime = 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 ) ;
GetHistoryAlarmData ( item . ProcessGuid , timeFrom , timeTo , item . Module ) ;
_lstTokenTimeData . TryTake ( out _ ) ;
}
}
}
}
catch ( Exception ex )
{
LOG . Error ( ex . Message ) ;
}
return true ;
}
protected bool MonitorRealTimeData ( )
{
try
{
if ( RealTimeMode & & _realTimeStart < DateTime . Now & & _lstTokenTimeData . Count = = 0 )
{
lock ( _lockSelection )
{
GetRealTimeData ( ) ;
}
}
}
catch ( Exception ex )
{
LOG . Error ( ex . Message ) ;
}
return true ;
}
private void GetRealTimeData ( )
{
long nowTickCount = DateTime . Now . Ticks ;
string colName = "" ;
string module = "PM1" ;
List < string > lstColumn = GetColumnList ( module ) ;
if ( lstColumn . Count < = 0 )
{
return ;
}
colName = String . Join ( "," , lstColumn ) ;
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" ,
DateTime . Now . ToString ( "yyyyMMdd" ) + "." + module , _realTimeTick , nowTickCount ) ;
_realTimeTick = nowTickCount ;
Dictionary < string , List < DataDetail > > historyData = new Dictionary < string , List < DataDetail > > ( ) ;
DataTable dataTable = QueryDataClient . Instance . Service . QueryData ( sql ) ;
if ( dataTable = = null | | dataTable . Rows . Count = = 0 | | dataTable . Columns . Count < 2 )
{
return ;
}
RealTimeX = ( ( long ) dataTable . Rows [ dataTable . Rows . Count - 1 ] [ 0 ] - _realTimeStart . Ticks ) / 10000000 ;
for ( int j = 1 ; j < dataTable . Columns . Count ; j + + )
{
List < DataDetail > lstDataDetail = new List < DataDetail > ( ) ;
for ( int i = 0 ; i < dataTable . Rows . Count ; i + + )
{
DataDetail data = new DataDetail ( ) ;
long ticks = ( long ) dataTable . Rows [ i ] [ 0 ] - _realTimeStart . Ticks ;
data . xValue = ticks / 10000000 ;
if ( dataTable . Rows [ i ] [ j ] is DBNull | | dataTable . Rows [ i ] [ j ] is null )
{
data . yValue = 0 ;
}
else if ( dataTable . Rows [ i ] [ j ] is bool )
{
data . yValue = ( bool ) dataTable . Rows [ i ] [ j ] ? 1 : 0 ;
}
else
{
data . yValue = float . Parse ( dataTable . Rows [ i ] [ j ] . ToString ( ) ) ;
}
lstDataDetail . Add ( data ) ;
}
historyData . Add ( dataTable . Columns [ j ] . ColumnName . Replace ( "PM1." , "" ) + "_" + _realTimeGuid , lstDataDetail ) ;
}
Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
try
{
foreach ( var item in SelectedData )
{
var seriesItem = item as ChartDataLineX ;
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 ) ;
}
} ) ) ;
}
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 > ( ) ;
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 ( ) ) ;
}
lstDataDetail . Add ( data ) ;
}
}
historyData . Add ( processGuid , lstDataDetail ) ;
Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
try
{
foreach ( var item in SelectedData )
{
var seriesItem = item as ChartDataLineX ;
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 ) ;
}
} ) ) ;
}
private void GetHistoryAlarmData ( string processguid , DateTime from , DateTime to , string module )
{
string sql = String . Format ( "select occur_time,description from public.event_data where source='{0}' and level='Alarm' and occur_time>'{1}' and occur_time<'{2}'" ,
module , from , to ) ;
DataTable dataTable = QueryDataClient . Instance . Service . QueryData ( sql ) ;
if ( dataTable = = null | | dataTable . Rows . Count = = 0 )
{
return ;
}
Application . Current . Dispatcher . BeginInvoke ( new Action ( ( ) = >
{
try
{
foreach ( var item in SelectedData )
{
var seriesItem = item as ChartDataLineX ;
if ( seriesItem . ProcessGuid = = processguid )
{
for ( int i = 0 ; i < dataTable . Rows . Count ; i + + )
{
long time = ( ( ( DateTime ) dataTable . Rows [ i ] [ "occur_time" ] ) . Ticks - from . Ticks ) / 10000000 ;
seriesItem . AppedAlarm ( time , dataTable . Rows [ i ] [ "description" ] . ToString ( ) ) ;
}
}
}
}
catch ( Exception ex )
{
LOG . Write ( ex ) ;
}
} ) ) ;
}
public bool ParameterCheck ( PMNodeInfo node )
{
if ( Recipes . Count < = 0 )
{
return false ;
}
if ( node . Selected )
{
foreach ( RecipeItemSic itemSic in Recipes )
{
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 ChartDataLineX ) . ProcessGuid = = nodeWithGuid ) ! = null ;
if ( ! isExist )
{
if ( SelectedData . Count < MAX_PARAMETERS )
{
var line = new ChartDataLineX ( nodeStr ) ;
line . ProcessGuid = nodeWithGuid ;
line . RecName = nodeStr_1 ;
line . Tag = node ;
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 ChartDataLineX ) . DataName . Contains ( node . NodeStr ) )
{
SelectedData . RemoveAt ( i ) ;
}
}
}
}
return true ;
}
public void SelectColor ( ChartDataLineX 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 } ;
}
}
public void SetYValue ( )
{
VisibleRangeYLimit = new DoubleRange ( Convert . ToDouble ( UseSetY1 ) , Convert . ToDouble ( UseSetY2 ) ) ;
}
public void SetXValue ( )
{
VisibleRangeXLimit = new DoubleRange ( Convert . ToDouble ( UseSetX1 ) , Convert . ToDouble ( UseSetX2 ) ) ;
}
/// <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 ;
}
/// <summary>
/// 搜索
/// </summary>
private void ApplyFilter ( )
{
foreach ( var node in ConfigNodes )
node . ApplyCriteria ( CurrentCriteria ) ;
}
public void SetTimeSpan ( )
{
if ( TrendInterval < 1000 )
{
TrendInterval = 1000 ;
}
else if ( TrendInterval > 60000 )
{
TrendInterval = 60000 ;
}
_threadReal . ChangeInterval ( TrendInterval ) ;
}
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 SetDataDetailVisble ( )
{
if ( DataDetailVisbility = = Visibility . Collapsed )
{
DataDetailVisbility = Visibility . Visible ;
}
else
{
DataDetailVisbility = Visibility . Collapsed ;
}
}
private void SetLegendAvalible ( )
{
ShowLegendInfo = ! ShowLegendInfo ;
}
private void Zoom ( )
{
ViewportManager . AnimateZoomExtents ( TimeSpan . FromMilliseconds ( 500 ) ) ;
}
public void DataStatistics ( )
{
foreach ( var item in SelectedData )
{
( item as ChartDataLineX ) . Caculate ( ThresholdX1 , ThresholdX2 ) ;
}
}
public void DataStatisticsReset ( )
{
ThresholdX1 = 0 ;
ThresholdX2 = 1 ;
}
//public void DataStatisticsCurrent()
//{
//}
public void AddRangeAnnotation ( )
{
AlarmAnnotation = new AnnotationCollection ( ) ;
VerticalLineAnnotation lineX1 = new VerticalLineAnnotation ( )
{
X1 = ThresholdX1 ,
VerticalAlignment = VerticalAlignment . Stretch ,
FontSize = 13 ,
FontWeight = FontWeights . Bold ,
IsEditable = true ,
LabelPlacement = LabelPlacement . Axis ,
LabelTextFormatting = "0.00" ,
ShowLabel = true ,
StrokeThickness = 2 ,
Stroke = System . Windows . Media . Brushes . Blue ,
Foreground = System . Windows . Media . Brushes . White ,
} ;
lineX1 . SetBinding ( VerticalLineAnnotation . X1Property , new Binding ( "ThresholdX1" ) { Mode = BindingMode . TwoWay } ) ;
AlarmAnnotation . Add ( lineX1 ) ;
VerticalLineAnnotation lineX2 = new VerticalLineAnnotation ( )
{
X1 = ThresholdX1 ,
VerticalAlignment = VerticalAlignment . Stretch ,
FontSize = 13 ,
FontWeight = FontWeights . Bold ,
IsEditable = true ,
LabelPlacement = LabelPlacement . Axis ,
LabelTextFormatting = "0.00" ,
ShowLabel = true ,
StrokeThickness = 2 ,
Stroke = System . Windows . Media . Brushes . Blue ,
Foreground = System . Windows . Media . Brushes . White ,
} ;
lineX2 . SetBinding ( VerticalLineAnnotation . X1Property , new Binding ( "ThresholdX2" ) { Mode = BindingMode . TwoWay } ) ;
AlarmAnnotation . Add ( lineX2 ) ;
}
private List < string > lstAlarmAdded = new List < string > ( ) ;
private bool _showAlarm = false ;
public void AddAlarmInfo ( )
{
lstAlarmAdded = new List < string > ( ) ;
while ( AlarmAnnotation . Count > 2 )
{
AlarmAnnotation . RemoveAt ( AlarmAnnotation . Count - 1 ) ;
}
_showAlarm = ! _showAlarm ;
if ( _showAlarm )
{
lock ( _lockSelection )
{
foreach ( var item in SelectedData )
{
var data = item as ChartDataLineX ;
if ( data . IsVisible & & data . ProcessGuid . Split ( '_' ) . Length = = 2 & & ! lstAlarmAdded . Contains ( data . ProcessGuid . Split ( '_' ) [ 1 ] ) )
{
lstAlarmAdded . Add ( data . ProcessGuid . Split ( '_' ) [ 1 ] ) ; //同一个Guid不重复添加
for ( int i = 0 ; i < data . _alarmData . Count ; i + + )
{
System . Windows . Media . DoubleCollection dc = new System . Windows . Media . DoubleCollection ( ) ;
dc . Add ( 5 ) ;
dc . Add ( 5 ) ;
AnnotationLabel lb = new AnnotationLabel ( ) { LabelPlacement = LabelPlacement . TopRight , Text = "Alarm" + data . _alarmData [ i ] . Item2 } ;
VerticalLineAnnotation alarm1 = new VerticalLineAnnotation ( )
{
X1 = data . _alarmData [ i ] . Item1 ,
VerticalAlignment = VerticalAlignment . Stretch ,
FontSize = 13 ,
FontWeight = FontWeights . Bold ,
IsEditable = true ,
LabelPlacement = LabelPlacement . Axis ,
StrokeThickness = 1 ,
Stroke = System . Windows . Media . Brushes . Brown ,
Foreground = System . Windows . Media . Brushes . White ,
StrokeDashArray = dc ,
AnnotationLabels = new ObservableCollection < AnnotationLabel > ( new List < AnnotationLabel > ( ) { lb } ) ,
} ;
alarm1 . IsEnabled = false ;
AlarmAnnotation . Add ( alarm1 ) ;
}
}
}
}
}
}
}
}