private void ExportGraphs(FieldGrid Grid, string Title, int Width, int Height) { if (Grid == null) { return; } int w = Grid.Width; Field[,] Cells = Grid.Cells; Field Cell; int x, y; bool TitleOutput = false; x = 0; foreach (string FieldName in Grid.XLabels) { List <DateTime> Timepoints = new List <DateTime> (); List <object> Values = new List <object> (); FieldNumeric Num; string Unit = string.Empty; int BooleanValues = 0; int NumericalValues = 0; y = 0; foreach (DateTime Timepoint in Grid.YAxis) { Cell = Cells [x, y]; if (Cell != null) { if ((Num = Cell as FieldNumeric) != null) { if (NumericalValues == 0) { NumericalValues = 1; Unit = Num.Unit; } else if (Unit != Num.Unit) { continue; } Timepoints.Add(Timepoint); Values.Add(Cell.GetValue()); } else if (Cell is FieldBoolean) { BooleanValues = 1; Timepoints.Add(Timepoint); Values.Add(Cell.GetValue()); } } y++; } if (Values.Count >= 2 && NumericalValues + BooleanValues == 1) { Variables v = new Variables(); Graph Graph; Bitmap Bmp; string ContentType = string.Empty; byte[] Data = null; v ["X"] = Timepoints.ToArray(); v ["Y"] = Values.ToArray(); v ["YLabel"] = Unit; try { if (NumericalValues == 1) { Graph = Expression.ParseCached("line2d(X,Y,'Red','',YLabel)").Evaluate(v) as Graph; } else { Graph = Expression.ParseCached("scatter2d(X,if Y then 1 else 0,5,'Red','',YLabel)").Evaluate(v) as Graph; } if (Graph == null) { Bmp = null; } else { Bmp = Graph.GetImage(Width, Height) as Bitmap; } Data = MimeUtilities.Encode(Bmp, out ContentType); } catch (Exception) { Bmp = null; } if (Bmp != null) { if (this.html.Length == 0) { this.html.Append("<html xmlns=\"http://jabber.org/protocol/xhtml-im\"><body xmlns=\"http://www.w3.org/1999/xhtml\">"); } if (!TitleOutput && !string.IsNullOrEmpty(Title)) { TitleOutput = true; this.html.Append("<h1>"); this.html.Append(XmlUtilities.Escape(Title)); this.html.Append("</h1>"); this.text.AppendLine(Title); } this.html.Append("<h2>"); this.html.Append(XmlUtilities.Escape(FieldName)); this.html.Append("</h2>"); this.html.Append("<p><img src=\"data:"); this.html.Append(ContentType); this.html.Append(";base64,"); this.html.Append(System.Convert.ToBase64String(Data, Base64FormattingOptions.None)); this.html.Append("\" width=\""); this.html.Append(Width.ToString()); this.html.Append("\" height=\""); this.html.Append(Height.ToString()); this.html.Append("\"/></p>"); this.text.AppendLine("[" + Width.ToString() + "x" + Height.ToString() + " image]"); EventHandler h = this.OnGridExportComplete; if (h != null) { try { h(this, new EventArgs()); } catch (Exception ex) { Log.Exception(ex); } } } } x++; } }
private static void HttpGetHistoryGraph(HttpServerResponse resp, HttpServerRequest req) { networkLed.High(); try { string ValueAxis; string ParameterName; string s; int Width, Height; if (!req.Query.TryGetValue("w", out s) || !int.TryParse(s, out Width) || Width <= 0 || Width > 2048) { throw new HttpException(HttpStatusCode.ClientError_BadRequest); } if (!req.Query.TryGetValue("h", out s) || !int.TryParse(s, out Height) || Height <= 0 || Height > 2048) { throw new HttpException(HttpStatusCode.ClientError_BadRequest); } if (!req.Query.TryGetValue("p", out s)) { throw new HttpException(HttpStatusCode.ClientError_BadRequest); } switch (s) { case "temp": ParameterName = "TemperatureC"; ValueAxis = "Temperature (C)"; break; case "light": ParameterName = "LightPercent"; ValueAxis = "Light (%)"; break; case "motion": ParameterName = "Motion"; ValueAxis = "Motion"; break; default: throw new HttpException(HttpStatusCode.ClientError_BadRequest); } if (!req.Query.TryGetValue("base", out s)) { throw new HttpException(HttpStatusCode.ClientError_BadRequest); } Variables v = new Variables(); DateTime Now = DateTime.Now; lock (synchObject) { switch (s) { case "sec": v ["Records"] = perSecond.ToArray(); resp.Expires = Now; break; case "min": v ["Records"] = perMinute.ToArray(); resp.Expires = new DateTime(Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, 0).AddMinutes(1); break; case "h": v ["Records"] = perHour.ToArray(); resp.Expires = new DateTime(Now.Year, Now.Month, Now.Day, Now.Hour, 0, 0).AddHours(1); break; case "day": v ["Records"] = perDay.ToArray(); resp.Expires = new DateTime(Now.Year, Now.Month, Now.Day, 0, 0, 0).AddDays(1); break; case "month": v ["Records"] = perMonth.ToArray(); resp.Expires = new DateTime(Now.Year, Now.Month, 1, 0, 0, 0).AddMonths(1); break; default: throw new HttpException(HttpStatusCode.ClientError_BadRequest); } } Graph Result; if (ParameterName == "Motion") { Result = Expression.ParseCached("scatter2d(Records.Timestamp,if (Values:=Records.Motion) then 1 else 0,5,if Values then 'Red' else 'Blue','','Motion')").Evaluate(v) as Graph; } else { Result = Expression.ParseCached("line2d(Records.Timestamp,Records." + ParameterName + ",'','" + ValueAxis + "')").Evaluate(v) as Graph; } Image Img = Result.GetImage(Width, Height); byte[] Data = MimeUtilities.Encode(Img, out s); resp.ContentType = s; resp.ReturnCode = HttpStatusCode.Successful_OK; resp.WriteBinary(Data); } finally { networkLed.Low(); } }