Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
SampleStatisticsCommand.cs
1using System;
3using System.Text;
4using System.Threading.Tasks;
10using Waher.Script;
14using Waher.Things;
17
19{
24 {
25 private readonly SampleStatisticsCommand[] embeddedReports;
26 private readonly string performanceId;
27 private readonly int titleId;
28 private readonly string title;
29 private readonly string unit;
30 private readonly string windowSize;
31 private readonly double? min;
32 private readonly double? max;
33
38 public SampleStatisticsCommand(string PerformanceId, int TitleId, string Title, string Unit,
39 double? Min, double? Max, string WindowSize, ServerAdminReportNode Report,
40 params SampleStatisticsCommand[] EmbeddedReports)
41 : base(Report)
42 {
43 this.performanceId = PerformanceId;
44 this.titleId = TitleId;
45 this.title = Title;
46 this.unit = Unit;
47 this.min = Min;
48 this.max = Max;
49 this.windowSize = WindowSize;
50 this.embeddedReports = EmbeddedReports;
51 }
52
53 [Page(1, "Time", 150)]
54 [Header(2, "From:")]
55 [ToolTip(3, "Search for records from this point in time.")]
56 public DateTime From = DateTime.Today.AddDays(-1);
57
58 [Page(1, "Time", 150)]
59 [Header(4, "To:")]
60 [ToolTip(5, "Search for records to this point in time.")]
61 public DateTime To = DateTime.Today.AddDays(1);
62
63 public override Task<string> GetNameAsync(Language Language)
64 {
65 return Language.GetStringAsync(typeof(SampleStatisticsCommand), 6, "Statistics...");
66 }
67
68 public override ICommand Copy()
69 {
70 return new SampleStatisticsCommand(this.performanceId, this.titleId, this.title,
71 this.unit, this.min, this.max, this.windowSize, (ServerAdminReportNode)this.Report,
72 this.embeddedReports)
73 {
74 From = this.From,
75 To = this.To
76 };
77 }
78
80 {
81 this.Execute(Query, Language);
82 return Task.CompletedTask;
83 }
84
85 private async void Execute(Query Query, Language Language)
86 {
87 try
88 {
89 await Query.Start();
90
91 string Title = await Language.GetStringAsync(typeof(SampleStatisticsCommand), this.titleId, this.title);
92 await Query.SetTitle(Title);
93 await Query.BeginSection(Title);
94
95 if (this.embeddedReports is null || this.embeddedReports.Length == 0)
96 {
97 await ReportGraph(Query, Language, this.From, this.To,
98 this.performanceId, this.titleId, this.title, this.unit,
99 this.min, this.max, this.windowSize);
100 }
101 else
102 {
103 foreach (SampleStatisticsCommand Report in this.embeddedReports)
104 {
105 await ReportGraph(Query, Language, this.From, this.To,
106 Report.performanceId, Report.titleId, Report.title,
107 Report.unit, this.min, this.max, Report.windowSize);
108 }
109 }
110
111 await Query.EndSection();
112 }
113 catch (Exception ex)
114 {
115 await Query.LogMessage(ex);
116 }
117 finally
118 {
119 await Query.Done();
120 }
121 }
122
123 private static async Task ReportGraph(Query Query, Language Language,
124 DateTime From, DateTime To, string PerformanceId, int TitleId,
125 string DefaultTitle, string Unit, double? MinValue, double? MaxValue,
126 string WindowSize)
127 {
128 try
129 {
130 if (To < From)
131 {
132 DateTime Temp = To;
133 To = From;
134 From = Temp;
135 }
136
137 List<Filter> Filters = new List<Filter>()
138 {
139 new FilterFieldEqualTo("Id", PerformanceId)
140 };
141
142 if (From > DateTime.MinValue)
143 Filters.Add(new FilterFieldGreaterOrEqualTo("Start", From));
144
145 if (To < DateTime.MaxValue)
146 Filters.Add(new FilterFieldLesserThan("Start", To));
147
148 await Query.SetStatus(await Language.GetStringAsync(typeof(SampleStatisticsCommand), 9, "Searching database..."));
149
150 IEnumerable<SampleStatistic> Records;
151
152 if (Filters.Count == 1)
153 Records = await Database.Find<SampleStatistic>(Filters[0], "Start");
154 else
155 Records = await Database.Find<SampleStatistic>(new FilterAnd(Filters.ToArray()), "Start");
156
157 string Title = await Language.GetStringAsync(typeof(SampleStatisticsCommand), TitleId, DefaultTitle);
158 await Query.BeginSection(Title);
159 try
160 {
161 int NrRecords = 0;
162
163 foreach (SampleStatistic Record in Records)
164 NrRecords++;
165
166 const int MaxRecords = 50;
167 bool ShowTable = NrRecords <= MaxRecords;
168 Unit ParsedUnit = Script.Units.Unit.Parse(Unit);
169
170 if (ShowTable)
171 {
172 await Query.NewTable("Statistics", Title, new Column[]
173 {
174 new Column("Start", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 10, "Start"),
175 null, null, null, null, ColumnAlignment.Left, null),
176 new Column("Stop", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 11, "Stop"),
177 null, null, null, null, ColumnAlignment.Left, null),
178 new Column("Count", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 12, "Count"),
179 null, null, null, null, ColumnAlignment.Right, null),
180 new Column("Mean", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 13, "Mean"),
181 null, null, null, null, ColumnAlignment.Right, null),
182 new Column("Variance", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 14, "Variance"),
183 null, null, null, null, ColumnAlignment.Right, null),
184 new Column("StdDev", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 15, "StdDev"),
185 null, null, null, null, ColumnAlignment.Right, null),
186 new Column("Min", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 16, "Min"),
187 null, null, null, null, ColumnAlignment.Right, null),
188 new Column("Max", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 17, "Max"),
189 null, null, null, null, ColumnAlignment.Right, null)
190 });
191
192 foreach (SampleStatistic Rec in Records)
193 {
194 await Query.NewRecords("Statistics", new Record(new object[]
195 {
196 Rec.Start,
197 Rec.Stop,
198 Rec.Count,
199 Rec.Mean.HasValue ? new PhysicalQuantity(Rec.Mean.Value, ParsedUnit) : null,
200 Rec.Variance,
201 Rec.StdDev,
202 Rec.Min.HasValue ? new PhysicalQuantity(Rec.Min.Value, ParsedUnit) : null,
203 Rec.Max.HasValue ? new PhysicalQuantity(Rec.Max.Value, ParsedUnit) : null
204 }));
205 }
206
207 await Query.TableDone("Statistics");
208 }
209 else
210 {
211 StringBuilder Markdown = new StringBuilder();
212
213 Markdown.Append(await Language.GetStringAsync(typeof(SampleStatisticsCommand), 18, "Number of records:"));
214 Markdown.Append(" **");
215 Markdown.Append(NrRecords.ToString());
216 Markdown.Append("**. (");
217 Markdown.Append((await Language.GetStringAsync(typeof(SampleStatisticsCommand), 19, "Table shown if %0% records or less.")).Replace("%0%", MaxRecords.ToString()));
218 Markdown.Append(")");
219
220 await Query.NewObject(new MarkdownContent(Markdown.ToString()));
221 }
222
223 await Query.SetStatus(await Language.GetStringAsync(typeof(SampleStatisticsCommand), 20, "Preparing graph."));
224
225 StringBuilder sb = new StringBuilder();
226
227 sb.AppendLine("StepX:=join([foreach Rec in RS do [Rec.Start,Rec.Stop]]);");
228 sb.AppendLine("StepMean:=join([foreach Rec in RS do [Rec.Mean,Rec.Mean]]);");
229 sb.AppendLine("RS2:=[Rec in RS:exists(Rec.StdDev)];");
230
231 if (MinValue.HasValue)
232 {
233 sb.Append("SubSigma(x,s):=Max(x-s,");
234 sb.Append(Expression.ToString(MinValue.Value));
235 sb.AppendLine(");");
236 }
237 else
238 sb.AppendLine("SubSigma(x,s):=x-s;");
239
240 if (MaxValue.HasValue)
241 {
242 sb.Append("AddSigma(x,s):=Min(x+s,");
243 sb.Append(Expression.ToString(MaxValue.Value));
244 sb.AppendLine(");");
245 }
246 else
247 sb.AppendLine("AddSigma(x,s):=x+s;");
248
249 sb.AppendLine("G:=sum([foreach Rec in RS do polygon2d([a:=Rec.Start,b:=Rec.Stop,b,a],[a:=Rec.Min,a,b:=Rec.Max,b],'Orange')])+");
250 sb.AppendLine("sum([foreach Rec in RS2 do polygon2d([a:=Rec.Start,b:=Rec.Stop,b,a],[a:=SubSigma(Rec.Mean,2*Rec.StdDev),a,b:=AddSigma(Rec.Mean,2*Rec.StdDev),b],'OrangeRed')])+");
251 sb.AppendLine("sum([foreach Rec in RS2 do polygon2d([a:=Rec.Start,b:=Rec.Stop,b,a],[a:=SubSigma(Rec.Mean,Rec.StdDev),a,b:=AddSigma(Rec.Mean,Rec.StdDev),b],'Red')])+");
252 sb.AppendLine("plot2dline(StepX,StepMean,'Black');");
253 sb.AppendLine("G.Title:=Title;");
254 sb.AppendLine("G.LabelX:=LabelX;");
255 sb.AppendLine("G.LabelY:=LabelY; ");
256 sb.AppendLine("G");
257
259 sb.ToString(),
260 new Variables()
261 {
264 { "RS", Records },
265 { "Title", Title },
266 { "LabelX", await Language.GetStringAsync(typeof(SampleStatisticsCommand), 1, "Time") },
267 { "LabelY", Unit }
268 }));
270 "legend(['Mean ('+WindowSize+')'," +
271 "'±σ ('+WindowSize+')'," +
272 "'±2σ ('+WindowSize+')'," +
273 "'Min-Max ('+WindowSize+')']," +
274 "['Black','Red','OrangeRed','Orange'],'White',4)",
275 new Variables()
276 {
277 { "WindowSize", WindowSize }
278 }));
279
280 await Query.SetStatus(string.Empty);
281 }
282 catch (Exception ex)
283 {
284 await Query.LogMessage(ex);
285 }
286 finally
287 {
288 await Query.EndSection();
289 }
290 }
291 catch (Exception ex)
292 {
293 await Query.LogMessage(ex);
294 }
295 }
296 }
297}
Class that can be used to encapsulate Markdown to be returned from a Web Service, bypassing any encod...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
Definition: Database.cs:238
This filter selects objects that conform to all child-filters provided.
Definition: FilterAnd.cs:10
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field greater or equal to a given value.
This filter selects objects that have a named field lesser than a given value.
ReportNode Report
Report node.
Contains information about a language.
Definition: Language.cs:17
Task< string > GetStringAsync(Type Type, int Id, string Default)
Gets the string value of a string ID. If no such string exists, a string is created with the default ...
Definition: Language.cs:209
Represents collected statistical information from a small portion of time.
Class managing a script expression.
Definition: Expression.cs:41
static Task< object > EvalAsync(string Script)
Evaluates script, in string format.
Definition: Expression.cs:5946
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4760
Base class for graphs.
Definition: Graph.cs:88
const string GraphHeightVariableName
Variable name for graph height
Definition: Graph.cs:117
const string GraphWidthVariableName
Variable name for graph width
Definition: Graph.cs:112
Represents a unit.
Definition: Unit.cs:16
Unit(Prefix Prefix, ICollection< UnitFactor > Factors)
Represents a unit.
Definition: Unit.cs:27
Collection of variables.
Definition: Variables.cs:25
Abstract base class for commands executing a server administrator report.
SampleStatisticsCommand(string PerformanceId, int TitleId, string Title, string Unit, double? Min, double? Max, string WindowSize, ServerAdminReportNode Report, params SampleStatisticsCommand[] EmbeddedReports)
Executes the HTTP Statistics report.
override Task< string > GetNameAsync(Language Language)
Gets the displayable name of the command.
override Task StartQueryExecutionAsync(Query Query, Language Language)
Starts the execution of a query.
Abstract base class for server report nodes, requiring admin privileges to be seen and executed.
Defines a column in a table.
Definition: Column.cs:30
Class handling the reception of data from a query.
Definition: Query.cs:12
Task TableDone(string TableId)
Reports a table as being complete.
Definition: Query.cs:327
Task EndSection()
Ends a section. Each call to BeginSection(string) must be followed by a call to EndSection().
Definition: Query.cs:504
Task NewObject(object Object)
Reports a new object.
Definition: Query.cs:354
Task Start()
Starts query execution.
Definition: Query.cs:213
Task NewRecords(string TableId, params Record[] Records)
Reports a new set of records in a table.
Definition: Query.cs:300
Task BeginSection(string Header)
Begins a new section. Sections can be nested. Each call to BeginSection(string) must be followed by a...
Definition: Query.cs:483
Task NewTable(string TableId, string TableName, params Column[] Columns)
Defines a new table in the query output.
Definition: Query.cs:272
Task LogMessage(Exception Exception)
Logs an Exception as a query message.
Definition: Query.cs:381
async Task Done()
Query execution completed.
Definition: Query.cs:241
Task SetStatus(string Status)
Sets the current status of the query execution.
Definition: Query.cs:457
Task SetTitle(string Title)
Sets the title of the report.
Definition: Query.cs:430
Defines a record in a table.
Definition: Record.cs:9
Interface for commands.
Definition: ICommand.cs:32
ColumnAlignment
Column alignment.
Definition: Column.cs:9