Last updated

Real-time

This is a simple tutorial which simulates real-time monitoring using the Time Series Widget.

# Real-Time Monitoring

import { Group } from "@int/geotoolkit/scene/Group.ts";
import { Rect } from "@int/geotoolkit/util/Rect.ts";
import { TimeSeriesWidget } from "@int/geotoolkit/widgets/TimeSeriesWidget.ts";
import { FillDirection } from "@int/geotoolkit/widgets/timeseries/FillDirection.ts";
import { FillType } from "@int/geotoolkit/widgets/timeseries/FillType.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { KnownColors } from "@int/geotoolkit/util/ColorUtil.ts";
import { Range } from "@int/geotoolkit/util/Range.ts";
import { PatternFactory } from "@int/geotoolkit/attributes/PatternFactory.ts";
import { DataTable } from "@int/geotoolkit/data/DataTable.ts";
import { DataTableView } from "@int/geotoolkit/data/DataTableView.ts";
import { data } from "/src/code/TimeSeries/data.ts";
let interval;
function createScene(canvas) {
  const MAX_INDEX = 1e3;
  const startDate = new Date().getTime();
  const data1 = data[0];
  const data2 = data[1];
  const data3 = data[2];
  const MAX_DATA_LENGTH = 350;
  let index = 0;
  let counter = 0;
  const dataTables = [
    getDataTableView([], "", [], ""),
    getDataTableView([], "", [], ""),
    getDataTableView([], "", [], "")
  ];
  const colors = [KnownColors.Orange, KnownColors.Blue, KnownColors.Green];
  const names = ["CALI", "DLT", "GR"];
  const units = ["INS", "US/FT", "API"];
  const customPattern = PatternFactory.getInstance().createPattern("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAQCAYAAABQrvyxAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAScwAAEnMBjCK5BwAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAAAo0lEQVRIS81WQQ6AIAzj/5/GaAIq26DVQDmYYEJ1XVtGyjmn8qR0Lu93dq3Am+K/FlFwq/EXgfanbBFKvCm+ZyePWEQW3fsbj/pcZZG2oUZthIDSIiOL1xBHRBiJvW/Mxg8JIAop9xgC7AnUFr8a/yKwa1B7CodTmO2kKujuIGOvFrODCimABpFVZnZGqFNox4zABFQej+xcm4lYR+lxbxI/SR1oUFAhMA7PXAAAAABJRU5ErkJggg==");
  const fillStyles = [
    "rgba(21,101,192,0.5)",
    "rgba(239,108,0,0.5)",
    "rgba(253,216,53,0.25)",
    {
      "color": "rgba(21,101,192,0.25)",
      "pattern": customPattern,
      "foreground": "rgba(21,101,192,0.5)"
    }
  ];
  function getDataTableView(values, valueUnit, indices, indexUnit) {
    const dataTable = new DataTable({
      "cols": [
        { "type": "number", "data": indices.slice() },
        { "type": "number", "data": values.slice() }
      ]
    });
    dataTable.getColumn(0).setUnit(indexUnit);
    dataTable.getColumn(1).setUnit(valueUnit);
    const dataTableView = new DataTableView(dataTable);
    return {
      "datatable": dataTable,
      "datatableview": dataTableView
    };
  }
  function configTools(widget2) {
    widget2.getToolByName("picking").setEnabled(false);
    widget2.getToolByName("cursor").setEnabled(false);
    widget2.getToolByName("scroll").setEnabled(false);
    widget2.disconnectTool(widget2.getToolByName("picking"));
    widget2.disconnectTool(widget2.getToolByName("cursor"));
    widget2.disconnectTool(widget2.getToolByName("scroll"));
  }
  function addCurves(widget2) {
    dataTables.forEach((dataTable, index2) => {
      widget2.addCurve({
        "name": names[index2],
        "uri": "//test//" + names[index2].toLowerCase(),
        "data": dataTable["datatableview"],
        "properties": {
          "autoscale": true,
          "unit": units[index2],
          "linestyle": {
            "color": colors[index2],
            "width": 1.5
          }
        }
      });
    });
  }
  function addFills(widget2) {
    widget2.addFill(
      "//test//dlt",
      "//test//gr",
      fillStyles[0],
      FillType.CurveToCurve,
      FillDirection.Top
    );
    widget2.addFill(
      "//test//dlt",
      "//test//gr",
      fillStyles[3],
      FillType.CurveToCurve,
      FillDirection.Bottom
    );
  }
  function createRealtimeWidget() {
    const options = {
      "model": new Group().setModelLimits(new Rect(startDate - 5 * 60 * 1e3, 0, startDate, 1)),
      "title": {
        "text": "Real-time Monitoring"
      },
      "legends": {
        "height": 25
      },
      "scrollbar": {
        "visible": false
      },
      "viewcache": true,
      "intervalbuttons": {
        "visible": true,
        "intervals": {
          "30s": 1e3 * 30,
          "1m": 1e3 * 60,
          "5m": 1e3 * 60 * 5
        }
      }
    };
    return new TimeSeriesWidget(options);
  }
  const range = new Range(startDate - 5 * 60 * 1e3, startDate);
  const widget = createRealtimeWidget();
  configTools(widget);
  addCurves(widget);
  addFills(widget);
  widget.setVisibleRange(range);
  const updateHandler = () => {
    const _index = startDate + counter * 1e3;
    const cd1 = data1[index];
    const cd2 = data2[index];
    const cd3 = data3[index];
    const currentRange = widget.getVisibleRange();
    range.setRange(_index - 5 * 60 * 1e3, _index);
    dataTables[0]["datatable"].addRow([_index, cd1]);
    dataTables[1]["datatable"].addRow([_index, cd2]);
    dataTables[2]["datatable"].addRow([_index, cd3]);
    dataTables.forEach((dataTable) => {
      const length = dataTable["datatableview"].getNumberOfRows();
      if (length > MAX_DATA_LENGTH) {
        dataTable["datatable"].removeRows(0);
      }
    });
    widget.setRange(range);
    widget.setVisibleRange(new Range(_index - (currentRange.getHigh() - currentRange.getLow()), _index));
    ++index;
    if (index >= MAX_INDEX) {
      index = 0;
    }
    ++counter;
  };
  interval = window.setInterval(updateHandler, 100);
  return new Plot({
    "canvaselement": canvas,
    "root": widget
  });
}
function dispose() {
  clearInterval(interval);
}
export { createScene, dispose };

createScene(document.querySelector('[ref="plot"]'));