diff --git a/FrameworkLocal/UIClient/CenterViews/DataLogs/DataHistory/DataViewModel.cs b/FrameworkLocal/UIClient/CenterViews/DataLogs/DataHistory/DataViewModel.cs
index 76288b8..5e7aab2 100644
--- a/FrameworkLocal/UIClient/CenterViews/DataLogs/DataHistory/DataViewModel.cs
+++ b/FrameworkLocal/UIClient/CenterViews/DataLogs/DataHistory/DataViewModel.cs
@@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Net.Configuration;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -209,8 +210,46 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
VisibleRangeTime = new DateRange(StartDateTime.AddMinutes(-5), EndDateTime.AddMinutes(5));
ChartAutoRange = AutoRange.Always;
+ var colorRandom = new Random();
+ var colorPattern = GetNewColorPatternQueue();
+
+ // 生成待显示的数据列表
SelectedData.Clear();
+ #region 生成曲线对象
+
+ foreach (var module in selectedModules)
+ {
+ var selectedTerminal = module.Flatten(true).Where(x => x.Selected == true);
+
+ foreach (var terminal in selectedTerminal)
+ {
+ var line2D = new SicFastLineSeries(terminal.FullName)
+ {
+ AntiAliasing = true,
+ ResamplingMode = ResamplingMode.MinMax
+ };
+
+ // 确保当列队未空时不会出错,选择默认黑色。
+ var color = colorPattern.Any()
+ ? colorPattern.Dequeue()
+ : Color.FromArgb(255, colorRandom.Next(0, 255), colorRandom.Next(0, 255),
+ colorRandom.Next(0, 255));
+
+ line2D.Stroke = System.Windows.Media.Color.FromRgb(color.R, color.G, color.B);
+
+ var ds = line2D.GetDataSeries();
+ ds.Tag = terminal;
+
+
+ SelectedData.Add(line2D);
+ }
+ }
+
+ #endregion
+
+ var dataSeriesList = SelectedData.Select(x => x.DataSeries).ToList();
+
BusyIndicatorContent = "Querying Data ...";
IsBusy = true;
_cancellationTokenSource = new CancellationTokenSource();
@@ -221,14 +260,14 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
var ts = EndDateTime - StartDateTime;
if (ts.Days <= 1)
{
- await Query(selectedModules, StartDateTime, EndDateTime, _cancellationTokenSource);
+ Query(selectedModules, dataSeriesList, StartDateTime, EndDateTime, _cancellationTokenSource);
}
else
{
var daySlices = Core.DateRange.SplitInToDays(new Core.DateRange(StartDateTime, EndDateTime));
foreach (var range in daySlices)
{
- await Query(selectedModules, range.Start, range.End, _cancellationTokenSource);
+ Query(selectedModules, dataSeriesList, range.Start, range.End, _cancellationTokenSource);
if (_cancellationTokenSource.Token.IsCancellationRequested)
break;
@@ -257,7 +296,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
///
/// 查询数据
///
- public async Task Query(IEnumerable selectedModules, DateTime startTime, DateTime endTime,
+ public void Query(IEnumerable selectedModules, List dataSeriesList, DateTime startTime, DateTime endTime,
CancellationTokenSource cancellation)
{
var sw = new Stopwatch();
@@ -267,7 +306,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
Debug.WriteLine("start to query data ....");
sw.Start();
#endif
- var ds = await SearchDataBaseAsync(selectedModules, startTime, endTime, cancellation);
+ var ds = SearchDataBaseAsync(selectedModules, startTime, endTime, cancellation);
#if DEBUG
sw.Stop();
Debug.WriteLine($"Data returned, costs {sw.ElapsedMilliseconds}ms....");
@@ -288,7 +327,8 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
Debug.WriteLine("start to render data ....");
sw.Restart();
#endif
- await RenderChartAndTable(ds, cancellation);
+ var t = RenderChartAndTable(ds, cancellation, dataSeriesList);
+ Task.WaitAll(t.ToArray());
#if DEBUG
sw.Stop();
Debug.WriteLine($"Data render done, costs {sw.ElapsedMilliseconds}ms....");
@@ -331,83 +371,80 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
/// 根据左侧选项查询数据
///
///
- private async Task SearchDataBaseAsync(IEnumerable modules, DateTime startTime, DateTime endTime, CancellationTokenSource cancellation)
+ private DataSet SearchDataBaseAsync(IEnumerable modules, DateTime startTime, DateTime endTime,
+ CancellationTokenSource cancellation)
{
if (cancellation == null)
throw new ArgumentNullException(nameof(cancellation), "cancellation object can not be null.");
var ds = new DataSet();
-
- return await Task.Run(() =>
+
+ try
{
- try
+ using (cancellation.Token.Register(Thread.CurrentThread.Abort))
{
- using (cancellation.Token.Register(Thread.CurrentThread.Abort))
+ // 遍历模组
+ foreach (var module in modules)
{
- // 遍历模组
- foreach (var module in modules)
+ var sql = new StringBuilder();
+ //! 因为数据库中按天拆表,无法一次性查询数据,需使用UNION合并多表查询,因此此处按天拼接SQL表达式
+ // 最终SQL表达式结构为:
+ // (select xx from date1.xx) union (select xx from date2.xx) union (select xx from date3.xx)
+ // where time between xxx and xxx
+ // order by time asc
+ var ts = endTime - startTime;
+ for (var day = 0; day <= ts.Days; day++)
{
- var sql = new StringBuilder();
- //! 因为数据库中按天拆表,无法一次性查询数据,需使用UNION合并多表查询,因此此处按天拼接SQL表达式
- // 最终SQL表达式结构为:
- // (select xx from date1.xx) union (select xx from date2.xx) union (select xx from date3.xx)
- // where time between xxx and xxx
- // order by time asc
- var ts = endTime - startTime;
- for (var day = 0; day <= ts.Days; day++)
+ // 检查表名是否存在,否则SQL执行出错。
+ var tblName = $"{startTime.AddDays(day):yyyyMMdd}.{module}";
+ if (CheckTableExists(tblName))
{
- // 检查表名是否存在,否则SQL执行出错。
- var tblName = $"{startTime.AddDays(day):yyyyMMdd}.{module}";
- if (CheckTableExists(tblName))
+
+ sql.Append("select \"time\" AS InternalTimeStamp");
+ var selectedParams = module.ChildNodes.FlattenNodes(true)
+ .Where(x => x.Selected == true);
+
+ // 添加待查询的列
+ foreach (var item in selectedParams)
{
-
- sql.Append("select \"time\" AS InternalTimeStamp");
- var selectedParams = module.ChildNodes.FlattenNodes(true)
- .Where(x => x.Selected == true);
-
- // 添加待查询的列
- foreach (var item in selectedParams)
- {
- sql.Append("," + $"\"{item}\"");
- }
-
- sql.Append($" from \"{tblName}\" ");
-
- if (day < ts.Days)
- sql.Append(" UNION ");
+ sql.Append("," + $"\"{item}\"");
}
+
+ sql.Append($" from \"{tblName}\" ");
+
+ if (day < ts.Days)
+ sql.Append(" UNION ");
}
-
- // 所有表名不可用,可能是日期范围错误
- if (sql.Length <= 0)
- {
- continue;
- }
-
- sql.Append(
- $" where \"time\" between {startTime.Ticks} and {endTime.Ticks} order by InternalTimeStamp asc");
-
- // 查询数据并将返回的结果存储在DataSet中
- var dataTable = QueryDataClient.Instance.Service.QueryData(sql.ToString());
-
- //! 返回的 DataTable 可能不存在,原因是上述代码自动生成的表明可能不存在。
- if (dataTable == null)
- continue;
- dataTable.TableName = module.Name;
- ds.Tables.Add(dataTable);
}
+
+ // 所有表名不可用,可能是日期范围错误
+ if (sql.Length <= 0)
+ {
+ continue;
+ }
+
+ sql.Append(
+ $" where \"time\" between {startTime.Ticks} and {endTime.Ticks} order by InternalTimeStamp asc");
+
+ // 查询数据并将返回的结果存储在DataSet中
+ var dataTable = QueryDataClient.Instance.Service.QueryData(sql.ToString());
+
+ //! 返回的 DataTable 可能不存在,原因是上述代码自动生成的表明可能不存在。
+ if (dataTable == null)
+ continue;
+ dataTable.TableName = module.Name;
+ ds.Tables.Add(dataTable);
}
}
- catch (ThreadAbortException)
- {
- // 操作被取消
- ds = null;
- throw;
- }
+ }
+ catch (ThreadAbortException)
+ {
+ // 操作被取消
+ ds = null;
+ throw;
+ }
- return ds;
-
- }, cancellation.Token);
+ return ds;
}
///
@@ -415,7 +452,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
///
///
///
- private async Task RenderChartAndTable(DataSet ds, CancellationTokenSource cancellation)
+ private List RenderChartAndTable(DataSet ds, CancellationTokenSource cancellation, List dataSeriesList)
{
if (cancellation == null)
throw new ArgumentNullException(nameof(cancellation), "cancellation object can not be null.");
@@ -429,10 +466,10 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
var appendTask = new List();
- var colorRandom = new Random();
- var colorPattern = GetNewColorPatternQueue();
+ /*var colorRandom = new Random();
+ var colorPattern = GetNewColorPatternQueue();*/
- // 当曲线的数据点添加完毕时属性统计值。
+ /*// 当曲线的数据点添加完毕时属性统计值。
IProgress> seriesAppendDone = new Progress>(series =>
{
if (series.Tag is ParameterNode node)
@@ -441,7 +478,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
node.MaxValue = node.RawData.Max(x => x.Value).ToString("F2");
node.AverageValue = node.RawData.Average(x => x.Value).ToString("F2");
}
- });
+ });*/
// 一个Table一个模组
foreach (var table in ds.Tables.Cast())
@@ -458,22 +495,24 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
var fullName = col.ColumnName;
- // 在SelectedData中检查是否曲线已经存在,若不存在,新建一个
+ /*// 在SelectedData中检查是否曲线已经存在,若不存在,新建一个
var line2D = SelectedData.Cast().FirstOrDefault(x => x.DataName == fullName);
if (line2D == null)
{
- line2D = new SicFastLineSeries(fullName)
+ line2D = new SicFastLineSeries(fullName)
{
AntiAliasing = true,
ResamplingMode = ResamplingMode.MinMax
};
- SelectedData.Add(line2D);
+ SelectedData.Add(line2D);
}
+
+
// 绑定LineChart对应的节点。
var node = ParameterNodes.FindTerminalByFullName(fullName);
-
+
// 确保当列队未空时不会出错,选择默认黑色。
var color = colorPattern.Any()
? colorPattern.Dequeue()
@@ -481,89 +520,110 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
colorRandom.Next(0, 255));
line2D.Stroke = System.Windows.Media.Color.FromRgb(color.R, color.G, color.B);
-
- var dataSeries = line2D.GetDataSeries();
+
+ var dataSeries = line2D.GetDataSeries();*/
+
+ var dataSeries =
+ dataSeriesList.FirstOrDefault(x => (x.Tag is ParameterNode node) && node.FullName == fullName);
+
if (dataSeries == null)
continue;
- // ParameterNode放在line2D.DataSeries.Tag中,而不是line2D.Tag中,因为ParameterNode需要从Task中抛给seriesAppendDone
+ /*// ParameterNode放在line2D.DataSeries.Tag中,而不是line2D.Tag中,因为ParameterNode需要从Task中抛给seriesAppendDone
// 进行数据统计,但Task中无法访问line2D对象,因为跨线程访问问题。
- dataSeries.Tag = node;
- var rawData = node.RawData;
+ dataSeries.Tag = node;*/
+ var rawData = (dataSeries.Tag as ParameterNode)?.RawData;
+ if(rawData == null)
+ continue;
+
#endregion
#if DEBUG
- Debug.WriteLine($"[{sw.ElapsedMilliseconds}ms] Appending point to series {line2D.DataName} ...");
+ Debug.WriteLine($"[{sw.ElapsedMilliseconds}ms] Appending point to series {fullName} ...");
#endif
//using (dataSeries.SuspendUpdates())
//{
- var t = Task.Run(() =>
+ var t = Task.Run(() =>
+ {
+#if DEBUG
+ Debug.WriteLine(
+ $"\t[{sw.ElapsedMilliseconds}ms] Start to appending data to {fullName} ...");
+#endif
+
+ // 限制LineChart.Points数量,提高显示速度。
+ const int RESTRICT_POINTS_IN_SERIES = 1000;
+
+ var rows = table.Rows;
+ var skippedRows = rows.Count / RESTRICT_POINTS_IN_SERIES;
+ if (skippedRows <= 0)
+ skippedRows = 1;
+
+ // 遍历数据行,添加数据点到LineChart。
+ var skipped = 0;
+
+ var dateList = new List();
+ var valueList = new List();
+ var metaList = new List();
+
+ for (var i = 0; i < rows.Count; i++)
{
-#if DEBUG
- Debug.WriteLine(
- $"\t[{sw.ElapsedMilliseconds}ms] Start to appending data to {line2D.DataName} ...");
-#endif
+ var date = new DateTime(long.Parse(rows[i][0].ToString()));
+ var cellValue = rows[i][col];
+ var value = double.NaN;
- // 限制LineChart.Points数量,提高显示速度。
- const int RESTRICT_POINTS_IN_SERIES = 1000;
+ if (cellValue is bool b)
+ value = b ? 1 : 0;
+ else if (double.TryParse(cellValue.ToString(), out var num))
+ value = num;
+ else
+ value = 0;
- var rows = table.Rows;
- var skippedRows = rows.Count / RESTRICT_POINTS_IN_SERIES;
- if (skippedRows <= 0)
- skippedRows = 1;
+ dateList.Add(date);
+ valueList.Add(value);
+ metaList.Add(new ParameterNodePoint(date, value));
- // 遍历数据行,添加数据点到LineChart。
- var skipped = 0;
- for (var i = 0; i < rows.Count; i++)
+ /*((XyDataSeries)dataSeries).Append(date, value, new ParameterNodePoint(date, value));
+ rawData.Add(new ParameterNodePoint(date, value));*/
+
+
+ /*// Re-sampling to improve the rendering performance.
+ if (skipped >= skippedRows)
{
- var date = new DateTime(long.Parse(rows[i][0].ToString()));
- var cellValue = rows[i][col];
- var value = double.NaN;
-
- if (cellValue is bool b)
- value = b ? 1 : 0;
- else if (double.TryParse(cellValue.ToString(), out var num))
- value = num;
- else
- value = 0;
-
dataSeries.Append(date, value, new ParameterNodePoint(date, value));
- rawData.Add(new ParameterNodePoint(date, value));
-
-
- /*// Re-sampling to improve the rendering performance.
- if (skipped >= skippedRows)
- {
- dataSeries.Append(date, value, new ParameterNodePoint(date, value));
- skipped = 0;
- }
- else
- {
- skipped++;
- }*/
-
-
- // 操作被取消
- if (cancellation.Token.IsCancellationRequested)
- return;
-
- //Thread.Sleep(1);
-
-
+ skipped = 0;
}
+ else
+ {
+ skipped++;
+ }*/
- //
- seriesAppendDone.Report(dataSeries);
+
+ // 操作被取消
+ if (cancellation.Token.IsCancellationRequested)
+ return;
+
+ //Thread.Sleep(1);
+
+
+ }
+
+ //
+ //seriesAppendDone.Report(dataSeries);
+
+ using (dataSeries.SuspendUpdates())
+ {
+ ((XyDataSeries)dataSeries).Append(dateList, valueList, metaList);
+ }
#if DEBUG
Debug.WriteLine(
- $"\t[{sw.ElapsedMilliseconds}ms] Finish appending data to {line2D.DataName}!");
+ $"\t[{sw.ElapsedMilliseconds}ms] Finish appending data to {fullName}!");
#endif
- });
+ });
- appendTask.Add(t);
+ appendTask.Add(t);
//}
//await Task.Delay(100);
@@ -575,7 +635,7 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
#endif
// 等待所有序列写入数据完成。
- await Task.WhenAll(appendTask);
+ //await Task.WhenAll(appendTask);
//}
@@ -585,6 +645,8 @@ namespace MECF.Framework.UI.Client.CenterViews.DataLogs.DataHistory
Debug.WriteLine($"[{sw.ElapsedMilliseconds}ms] Method {nameof(RenderChartAndTable)} Done!");
sw.Stop();
#endif
+
+ return appendTask;
}
#region Parameter Grid Control
diff --git a/FrameworkLocal/output/MECF.Framework/MECF.Framework.RT.Core.dll b/FrameworkLocal/output/MECF.Framework/MECF.Framework.RT.Core.dll
index e599302..a08883c 100644
Binary files a/FrameworkLocal/output/MECF.Framework/MECF.Framework.RT.Core.dll and b/FrameworkLocal/output/MECF.Framework/MECF.Framework.RT.Core.dll differ
diff --git a/FrameworkLocal/output/MECF.Framework/MECF.Framework.Simulator.Core.dll b/FrameworkLocal/output/MECF.Framework/MECF.Framework.Simulator.Core.dll
index 590b257..2d28f2f 100644
Binary files a/FrameworkLocal/output/MECF.Framework/MECF.Framework.Simulator.Core.dll and b/FrameworkLocal/output/MECF.Framework/MECF.Framework.Simulator.Core.dll differ
diff --git a/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Client.dll b/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Client.dll
index 5aa1b92..628a25c 100644
Binary files a/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Client.dll and b/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Client.dll differ
diff --git a/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Core.dll b/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Core.dll
index 4b768cf..5eb909c 100644
Binary files a/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Core.dll and b/FrameworkLocal/output/MECF.Framework/MECF.Framework.UI.Core.dll differ