Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CustomGraph.cs
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Text;
5using System.Threading.Tasks;
6using System.Xml;
8using Waher.Content;
12
14{
19 {
20 private readonly LinkedList<KeyValuePair<DateTime, double>> statistics = new LinkedList<KeyValuePair<DateTime, double>>();
21 private string @for;
22 private string script;
23 private StringBuilder times = null;
24 private StringBuilder values = null;
25 private IFilter filter = null;
26 private DateTime start;
27 private DateTime stop;
28 private Duration bucketTime;
29 private Unit unit = null;
30 private int count = 0;
31 private long last = 0;
32
39 : base(Parent, Model)
40 {
41 }
42
46 public override string LocalName => nameof(CustomGraph);
47
51 public string For => this.@for;
52
56 public string Id => this.For;
57
61 public long TotalCount => this.count;
62
67 {
68 get => this.bucketTime;
69 set => this.bucketTime = value;
70 }
71
79 {
80 return new CustomGraph(Parent, Model);
81 }
82
86 public override bool ParseChildren => false;
87
92 public override Task FromXml(XmlElement Definition)
93 {
94 this.@for = XML.Attribute(Definition, "for");
95
96 if (Definition.HasAttribute("timeVariable"))
97 {
98 this.times = new StringBuilder();
99 this.times.Append(Definition.GetAttribute("timeVariable"));
100 this.times.Append(":=[");
101 }
102
103 this.values = new StringBuilder();
104
105 if (Definition.HasAttribute("valueVariable"))
106 this.values.Append(Definition.GetAttribute("valueVariable"));
107 else
108 this.values.Append(this.@for);
109
110 this.values.Append(":=[");
111
112 this.script = Values.Script.RemoveIndent(Definition.InnerText);
113
114 return Task.CompletedTask;
115 }
116
120 public override Task Start()
121 {
122 this.start = this.Model.StartTime;
123 this.bucketTime = this.Model.BucketTime;
124 this.stop = this.start + this.bucketTime;
125
126 return base.Start();
127 }
128
133 public DateTime Inc()
134 {
135 DateTime Timestamp = DateTime.Now;
136 double v;
137
138 lock (this)
139 {
140 v = ++this.last;
141 }
142
143 return this.Sample(Timestamp, v);
144 }
145
150 public DateTime Dec()
151 {
152 DateTime Timestamp = DateTime.Now;
153 double v;
154
155 lock (this)
156 {
157 v = --this.last;
158 }
159
160 return this.Sample(Timestamp, v);
161 }
162
169 public DateTime Sample(DateTime Timestamp, PhysicalQuantity Value)
170 {
171 double v;
172
173 if (this.unit is null)
174 {
175 this.unit = Value.Unit;
176 v = Value.Magnitude;
177 }
178 else if (!Unit.TryConvert(Value.Magnitude, Value.Unit, this.unit, out v))
179 throw new Exception("Incompatible units: " + Value.Unit.ToString() + " and " + this.unit.ToString());
180
181 return this.Sample(Timestamp, v);
182 }
183
190 public DateTime Sample(DateTime Timestamp, double Value)
191 {
192 if (this.filter?.Filter(ref Timestamp, ref Value) ?? false)
193 return this.start;
194
195 lock (this)
196 {
197 while (Timestamp >= this.stop)
198 {
199 this.start = this.stop;
200 this.stop = this.start + this.bucketTime;
201 }
202
203 if (!(this.times is null))
204 {
205 if (this.count > 0)
206 this.times.Append(',');
207
208 this.times.Append(CommonTypes.Encode(this.Model.GetTimeCoordinates(Timestamp)));
209 }
210
211 if (!(this.values is null))
212 {
213 if (this.count > 0)
214 this.values.Append(',');
215
216 this.values.Append(CommonTypes.Encode(Value));
217 }
218
219 this.statistics.AddLast(new KeyValuePair<DateTime, double>(Timestamp, Value));
220 this.count++;
221
222 return this.start;
223 }
224 }
225
231 public DateTime CountOccurrence(DateTime Timestamp)
232 {
233 double v;
234
235 lock (this)
236 {
237 v = ++this.last;
238 }
239
240 return this.Sample(Timestamp, v);
241 }
242
246 public void Flush()
247 {
248 }
249
255 public void ExportXml(XmlWriter Output, string RowElement)
256 {
257 this.Flush();
258
259 lock (this)
260 {
261 Output.WriteStartElement(RowElement);
262 Output.WriteAttributeString("type", this.@for);
263 Output.WriteAttributeString("count", this.count.ToString());
264
265 if (!(this.unit is null))
266 Output.WriteAttributeString("unit", this.unit.ToString());
267
268 foreach (KeyValuePair<DateTime, double> Rec in this.statistics)
269 {
270 Output.WriteStartElement("Stat");
271 Output.WriteAttributeString("ts", XML.Encode(Rec.Key));
272 Output.WriteAttributeString("value", CommonTypes.Encode(Rec.Value));
273 Output.WriteEndElement();
274 }
275
276 Output.WriteEndElement();
277 }
278 }
279
284 public override void ExportGraph(StreamWriter Output)
285 {
286 this.Flush();
287
288 lock (this)
289 {
290 Output.WriteLine("{");
291
292 if (this.count > 0)
293 {
294 if (!(this.times is null))
295 {
296 Output.Write(this.times.ToString());
297 Output.WriteLine("];");
298 }
299
300 if (!(this.values is null))
301 {
302 Output.Write(this.values.ToString());
303 Output.WriteLine("];");
304 }
305 }
306
307 Output.WriteLine("GraphWidth:=1000;");
308 Output.WriteLine("GraphHeight:=400;");
309 this.ExportGraphScript(Output, null, true);
310 Output.WriteLine(";");
311 Output.WriteLine("}");
312 Output.WriteLine();
313 }
314 }
315
323 public override bool ExportGraphScript(StreamWriter Output, string CustomColor, bool Span)
324 {
325 string s = this.script.Trim();
326 if (!string.IsNullOrEmpty(s) && ";|<>/\\]}".IndexOf(s[s.Length - 1]) >= 0)
327 s = s.Substring(0, s.Length - 1);
328
329 Output.Write(s);
330
331 return true;
332 }
333
338 public void Add(IFilter Filter)
339 {
340 if (this.filter is null)
341 this.filter = Filter;
342 else
343 this.filter.Append(Filter);
344 }
345
346 }
347}
Root node of a simulation model
Definition: Model.cs:49
DateTime StartTime
Start time
Definition: Model.cs:165
Duration BucketTime
Time to collect events, for statistical purposes.
Definition: Model.cs:155
Defines a custom graph (for a counter, variable, sample, etc.)
Definition: CustomGraph.cs:19
override Task Start()
Starts the node.
Definition: CustomGraph.cs:120
DateTime Dec()
Decrements counter.
Definition: CustomGraph.cs:150
override Task FromXml(XmlElement Definition)
Sets properties and attributes of class in accordance with XML definition.
Definition: CustomGraph.cs:92
void ExportXml(XmlWriter Output, string RowElement)
Exports data to XML
Definition: CustomGraph.cs:255
string For
If the graph represents the visualization of a given entity. (Otherwise, null, or the empty string....
Definition: CustomGraph.cs:51
override bool ExportGraphScript(StreamWriter Output, string CustomColor, bool Span)
Exports the graph to a markdown output.
Definition: CustomGraph.cs:323
Duration BucketTime
Time to accumulate values.
Definition: CustomGraph.cs:67
void Flush()
Terminates the ongoing collection of data.
Definition: CustomGraph.cs:246
override string LocalName
Local name of XML element defining contents of class.
Definition: CustomGraph.cs:46
override bool ParseChildren
If children are to be parsed by FromXml(XmlElement)
Definition: CustomGraph.cs:86
override void ExportGraph(StreamWriter Output)
Exports the graph to a markdown output.
Definition: CustomGraph.cs:284
DateTime Inc()
Increments counter.
Definition: CustomGraph.cs:133
void Add(IFilter Filter)
Adds a filter to the bucket.
Definition: CustomGraph.cs:338
CustomGraph(ISimulationNode Parent, Model Model)
Defines a custom graph (for a counter, variable, sample, etc.)
Definition: CustomGraph.cs:38
DateTime Sample(DateTime Timestamp, PhysicalQuantity Value)
Adds a sample
Definition: CustomGraph.cs:169
override ISimulationNode Create(ISimulationNode Parent, Model Model)
Creates a new instance of the node.
Definition: CustomGraph.cs:78
DateTime Sample(DateTime Timestamp, double Value)
Adds a sample
Definition: CustomGraph.cs:190
DateTime CountOccurrence(DateTime Timestamp)
Counts one occurrence
Definition: CustomGraph.cs:231
Abstract base class for graph nodes
Definition: Graph.cs:13
ISimulationNode Parent
Parent node in the simulation model.
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:594
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
Definition: XML.cs:914
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Represents a unit.
Definition: Unit.cs:15
static bool TryConvert(double From, Unit FromUnit, Unit ToUnit, out double To)
Tries to convert a magnitude in one unit to a magnitude in another.
Definition: Unit.cs:1201
override string ToString()
Definition: Unit.cs:517
Basic interface for simulator nodes. Implementing this interface allows classes with default contruct...
Interface for custom graph nodes
Definition: ICustomGraph.cs:9
Interface for buckets.
Definition: IBucket.cs:13
Interface for sample filters
Definition: IFilter.cs:9
void Append(IFilter Filter)
Appends a filter to the current filter.
Represents a duration value, as defined by the xsd:duration data type: http://www....
Definition: Duration.cs:13