commit b4b32b0eb22a71a0d211eda7d982751784eae8f9
Author: Štěpán Červenka <stepan.cervenka1@gmail.com>
Date:   Mon May 3 15:28:47 2021 +0200

    Re #8807 - Opravy
    
    + add observations support

diff --git a/.gitignore b/.gitignore
index 86d943a..e784378 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,4 @@ testem.log
 # System Files
 .DS_Store
 Thumbs.db
+/src/app/vega-analyze/
diff --git a/src/app/sensor/components/sensor.component.ts b/src/app/sensor/components/sensor.component.ts
index 8960103..300dabe 100644
--- a/src/app/sensor/components/sensor.component.ts
+++ b/src/app/sensor/components/sensor.component.ts
@@ -61,7 +61,7 @@ export class SensorComponent implements OnInit {
       }
     }
 
-/*    this.observationService.getObservation({
+   this.observationService.getObservation({
       unit_id: this.unitId,
       sensor_id: this.sensorId,
       from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
@@ -69,11 +69,13 @@ export class SensorComponent implements OnInit {
     }).subscribe(
       observations => {
         if (observations) {
-          // this.getGraph(this.sensorId, observations, 1800);
+          GraphLoader.getObservationGraph(this.sensorId, observations, "#view");
         }
-      });*/
+      });
 
-    if (this.selectedAggregationFunction) {
+
+
+   /* if (this.selectedAggregationFunction) {
       agg = this.selectedAggregationFunction;
     }
 
@@ -89,7 +91,7 @@ export class SensorComponent implements OnInit {
           GraphLoader.getGraph(null, null, null, null);
         }
       }
-    );
+    );*/
 
   }
 }
diff --git a/src/app/shared/graph-loading/graphloader.ts b/src/app/shared/graph-loading/graphloader.ts
index d447f72..ce434b7 100644
--- a/src/app/shared/graph-loading/graphloader.ts
+++ b/src/app/shared/graph-loading/graphloader.ts
@@ -37,11 +37,23 @@ export class GraphLoader {
     }
   }
 
+  static getObservationSpec(sensorId) {
+    const lodash = require('lodash/object');
+
+    const rvalue: any = {};
+    const base = require('/src/vega/base/default.json');
+    const chart = require('/src/vega/body/linechart-observations.json');
+    const tooltip = require('/src/vega/tooltip/value-tooltip.json')
+    lodash.merge(rvalue, base, chart, tooltip);
+    return rvalue;
+
+  }
+
   static getGraph(sensorId, data, interval, element) {
     const spec = this.getGraphType(sensorId);
     const vega = require('vega');
     const vegaTooltip = require('vega-tooltip');
-    const config = require('/src/vega/config.json');
+    const config = require('/src/vega/config/config-analytics.json');
 
     spec.data[0].values = data;
     spec.signals[0].value = interval;
@@ -74,6 +86,45 @@ export class GraphLoader {
 
 
 
+  }
+
+  static getObservationGraph(sensorId, data, element) {
+
+    const spec = this.getObservationSpec(sensorId);
+    const vega = require('vega');
+    const vegaTooltip = require('vega-tooltip');
+    const config = require('/src/vega/config/config-observations.json');
+
+    spec.data[0].values = data;
+    spec.signals[0].value = 3600;
+
+    const handler = new vegaTooltip.Handler();
+
+    const loc = vega.locale({
+      decimal: ',',
+      thousands: '\u00a0',
+      grouping: [3],
+      currency: ['', '\u00a0Kč']
+    },{
+      dateTime: '%A,%e.%B %Y, %X',
+      date: '%-d.%-m.%Y',
+      time: '%H:%M:%S',
+      periods: ['AM', 'PM'],
+      days: ['neděle', 'pondělí', 'úterý', 'středa', 'čvrtek', 'pátek', 'sobota'],
+      shortDays: ['ne.', 'po.', 'út.', 'st.', 'čt.', 'pá.', 'so.'],
+      months: ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
+      shortMonths: ['led', 'úno', 'břez', 'dub', 'kvě', 'čer', 'červ', 'srp', 'zář', 'říj', 'list', 'pros']
+    });
+
+    const view = new vega.View(vega.parse(spec, config))
+      .tooltip(handler.call)
+      .initialize(element)
+      .hover()
+      .locale(loc)
+      .runAsync();
+
+
+
   }
 
 }
diff --git a/src/app/unit/components/unit.component.ts b/src/app/unit/components/unit.component.ts
index e09c4fa..56a53e1 100644
--- a/src/app/unit/components/unit.component.ts
+++ b/src/app/unit/components/unit.component.ts
@@ -64,13 +64,6 @@ export class UnitComponent implements OnInit {
       from: moment(range[0]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3),
       to: moment(range[1]).format('yyyy-MM-DD HH:mm:ssZ').slice(0, -3), interval: agg}).pipe(
       tap(data => {
-        // this.data = Object.entries(data);
-        // console.log(this.data);
-
-        // for (const [key, value] of Object.entries(data)) {
-        //  console.log(key, Object.entries(value));
-        // }
-
         var objectKeys = Object.keys(data);
         for(const key of objectKeys ) {
           let element = this.createView();
diff --git a/src/vega/base/default.json b/src/vega/base/default.json
index c7306d6..7d15ac3 100644
--- a/src/vega/base/default.json
+++ b/src/vega/base/default.json
@@ -22,7 +22,7 @@
         },
         {
           "type": "formula",
-          "expr": "utcParse(datum[\"timestamp\"], '%Y-%m-%d %H:%M:%S.%f%Z')",
+          "expr": "toDate(datum[\"timestamp\"])",
           "as": "dateTime"
         }
       ]
diff --git a/src/vega/body/linechart-observations.json b/src/vega/body/linechart-observations.json
new file mode 100644
index 0000000..8485361
--- /dev/null
+++ b/src/vega/body/linechart-observations.json
@@ -0,0 +1,237 @@
+{
+  "data": [
+    {},
+    {},
+    {},
+    {
+      "name": "ranks",
+      "source": "table",
+      "transform": [
+        {
+          "type": "window",
+          "sort": {
+            "field": "dateTime",
+            "order": "ascending"
+          },
+          "ops": [
+            "rank"
+          ],
+          "fields": [
+            "value"
+          ],
+          "as": [
+            "rank"
+          ]
+        },
+        {
+          "type": "formula",
+          "expr": "datum.rank + 1",
+          "as": "nextRank"
+        }
+      ]
+    },
+    {
+      "name": "lookup",
+      "source": "ranks",
+      "transform": [
+        {
+          "type": "lookup",
+          "from": "ranks",
+          "key": "rank",
+          "fields": [
+            "nextRank"
+          ],
+          "as": [
+            "tempObj"
+          ]
+        },
+        {
+          "type": "formula",
+          "expr": "(datum.tempObj == null || datum.tempObj.dateTime - datum.dateTime > maxTimeDifference) ? null : datum.tempObj",
+          "as": "obj"
+        }
+      ]
+    }
+  ],
+  "marks": [
+    {
+      "scales": [
+        {},
+        {
+          "name": "yDetail",
+          "type": "linear",
+          "range": [390, 0],
+          "domain": {
+            "fields": [
+              {"data": "range", "field": "valueMax"},
+              {"data":  "table", "field": "value"}
+            ]
+          },
+          "nice": true, "zero": true
+        }
+      ],
+      "axes": [
+        {},
+        {"orient": "left", "scale": "yDetail"}
+      ],
+      "marks": [
+        {
+          "marks": [
+            {
+              "type": "symbol",
+              "from": {"data":"lookup"},
+              "encode": {
+                "enter": {
+                  "tooltip": {
+                    "signal": "{title: timeFormat(datum.dateTime, '%A, %e. %B %Y, %X') }"
+                  }},
+                "update": {
+                  "shape": {"value": "circle"},
+                  "size": {"value": 30},
+                  "x": {"scale": "xDetail", "field": "dateTime"},
+                  "y": {"scale": "yDetail", "field": "value"},
+                  "color": {"value": "both"},
+                  "strokeWidth": {"value": 4},
+                  "fill": {"value": "steelblue"}
+                },
+                "hover": {
+                  "fill": {"value": "red"},
+                  "size": {"value": 60}
+                }
+              }
+            },
+            {
+              "type": "rule",
+              "from": {
+                "data": "lookup"
+              },
+              "encode": {
+                "update": {
+                  "x": {
+                    "scale": "xDetail",
+                    "field": "dateTime"
+                  },
+                  "x2": [
+                    {
+                      "test": "isValid(datum.obj)",
+                      "scale": "xDetail",
+                      "field": "obj.dateTime"
+                    },
+                    {
+                      "scale": "xDetail",
+                      "field": "dateTime"
+                    }
+                  ],
+                  "y": {
+                    "scale": "yDetail",
+                    "field": "value"
+                  },
+                  "y2": [
+                    {
+                      "test": "isValid(datum.obj)",
+                      "scale": "yDetail",
+                      "field": "obj.value"
+                    },
+                    {
+                      "scale": "yDetail",
+                      "field": "value"
+                    }
+                  ],
+                  "stroke": {
+                    "value": "steelblue"
+                  },
+                  "strokeWidth": {
+                    "value": 1
+                  }
+                }
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "signals": [
+        {
+          "value": 0,
+          "on": [
+            {},
+            {
+              "events": "@overview:mousedown",
+              "update": "[x(), x()]"
+            },
+            {
+              "events": "[@overview:mousedown, window:mouseup] > window:mousemove!",
+              "update": "[brush[0], clamp(x(), 0, width)]"
+            }
+          ]
+        }
+      ],
+      "marks": [
+        {},
+        {},
+        {},
+        {
+          "type": "symbol",
+          "from": {"data":"table"},
+          "encode": {
+            "update": {
+              "shape": {"value": "circle"},
+              "size": {"value": 10},
+              "x": {"scale": "xOverview", "field": "dateTime"},
+              "y": {"scale": "yOverview", "field": "value"},
+              "color": {"value": "both"},
+              "strokeWidth": {"value": 4}
+            }
+          }
+        },
+        {
+          "type": "rule",
+          "from": {
+            "data": "lookup"
+          },
+          "encode": {
+            "update": {
+              "x": {
+                "scale": "xOverview",
+                "field": "dateTime"
+              },
+              "x2": [
+                {
+                  "test": "isValid(datum.obj)",
+                  "scale": "xOverview",
+                  "field": "obj.dateTime"
+                },
+                {
+                  "scale": "xOverview",
+                  "field": "dateTime"
+                }
+              ],
+              "y": {
+                "scale": "yOverview",
+                "field": "value"
+              },
+              "y2": [
+                {
+                  "test": "isValid(datum.obj)",
+                  "scale": "yOverview",
+                  "field": "obj.value"
+                },
+                {
+                  "scale": "yOverview",
+                  "field": "value"
+                }
+              ],
+              "stroke": {
+                "value": "steelblue"
+              },
+              "strokeWidth": {
+                "value": 1
+              }
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/src/vega/config.json b/src/vega/config.json
deleted file mode 100644
index 4350bef..0000000
--- a/src/vega/config.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "$schema": "https://vega.github.io/schema/vega/v5.json",
-  "width": 800,
-  "height": 200,
-  "padding": 5,
-  "signals": [
-    {"name": "valuePath", "value": "avg"},
-    {"name":  "timestampPath", "value":  "timestamp"},
-    {"name":  "detailHeight", "value": 390},
-    {"name": "overviewHeight", "value":  70},
-    {"name":  "overviewHeightStart", "value" : 430}
-  ]
-}
diff --git a/src/vega/config/config-analytics.json b/src/vega/config/config-analytics.json
new file mode 100644
index 0000000..de077cc
--- /dev/null
+++ b/src/vega/config/config-analytics.json
@@ -0,0 +1,14 @@
+{
+  "$schema": "https://vega.github.io/schema/vega/v5.json",
+  "width": 800,
+  "height": 200,
+  "padding": 5,
+  "signals": [
+    {"name": "valuePath", "value": "avg"},
+    {"name":  "timestampPath", "value":  "timestamp"},
+    {"name":  "detailHeight", "value": 390},
+    {"name": "overviewHeight", "value":  70},
+    {"name":  "overviewHeightStart", "value" : 430},
+    {"name":  "maxTimeDifference", "value": 10000000}
+  ]
+}
diff --git a/src/vega/config/config-observations.json b/src/vega/config/config-observations.json
new file mode 100644
index 0000000..74a9599
--- /dev/null
+++ b/src/vega/config/config-observations.json
@@ -0,0 +1,14 @@
+{
+  "$schema": "https://vega.github.io/schema/vega/v5.json",
+  "width": 800,
+  "height": 200,
+  "padding": 5,
+  "signals": [
+    {"name": "valuePath", "value": "value"},
+    {"name":  "timestampPath", "value":  "time"},
+    {"name":  "detailHeight", "value": 390},
+    {"name": "overviewHeight", "value":  70},
+    {"name":  "overviewHeightStart", "value" : 430},
+    {"name":  "maxTimeDifference", "value": 10000000}
+  ]
+}
diff --git a/src/vega/tooltip/value-tooltip.json b/src/vega/tooltip/value-tooltip.json
new file mode 100644
index 0000000..6e6f8c9
--- /dev/null
+++ b/src/vega/tooltip/value-tooltip.json
@@ -0,0 +1,42 @@
+{
+  "data": [
+    {},
+    {
+      "transform": [
+        {
+          "fields": [
+            {"signal" :  "valuePath"},
+            {"signal":  "timestampPath"},
+            "gid"
+
+          ],
+          "as": [
+            "value",
+            "timestamp",
+            "gid"
+          ]
+        }
+      ]
+    }
+  ],
+  "marks": [
+    {
+      "marks": [
+        {
+          "marks": [
+            {
+              "encode": {
+                "enter": {
+                  "tooltip": {
+                    "signal": "{title: timeFormat(datum.dateTime, '%A, %e. %B %Y, %X')  ,  'value': datum.value, 'gid': datum.gid }"
+                  }}
+              }
+
+
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
