{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. index::\n", " single: Line Chart\n", ".. index::\n", " single: InfluxDB; Line Chart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Line Chart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Line Chart instrument is a graphical display tool which brings you [Grafana](../influxdb/influxdb.ipynb#Grafana) type of monitoring tool inside an ordinary Dashboard instrument pane." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ">_Why not Grafana, then?_ - [OpenCPN](https://opencpn.org/) is based on [wxWidgets](https://www.wxwidgets.org/) cross-platform GUI library. It allows _OpenCPN_ to be available on large number of different platforms. The price to pay is that _wxWidgets_ needs to be extremely conservative on its implementing back-ends. The _wxWebView_ component is needed here and its back-end browser technology is very old. For example, on Windows it is at the level of _Internet Explorer_ 8 or, at best IE11! One cannot run modern web-developments on it but _DashT_ takes a modern line graph library [tui.chart](https://github.com/nhn/tui.chart), [polyfills](https://en.wikipedia.org/wiki/Polyfill_(programming)) it, and writes for you software which allowing to use [InfluxDB](../influxdb/influxdb.ipynb#Introduction) aggregation methods on the data read back from that very same time series database. Resulting function is similar to the to the popular functions provided by _Grafana_." ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. index::\n", " single: Line Chart; Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's take a look at the data we are recording already with [InfluxDB Out](../idbout/idbout.ipynb#InfluxDB-Out) into the [InfluxDB](../influxdb/influxdb.ipynb#Introduction) time-series database. The database is not only a bunch of buckets where it collects data but it has also its own set of aggregation functions which can be used to analyze and further filter the raw data and return that data to the sender, such as _DashT_. Typical use is with off-line analysis which is described below." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ">**NOTE**: _InfluxDB_ also sports its own Dashboard layout graphical user interface/application which you are encouraged to study!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this use case, we are interested in finding rapidly the tendencies in the Speed Through Water (STW), indicating that we are losing the speed. In our instruments our paddle wheel produced data is going unfiltered and jumping up and down so it is no easy to tell anything about tendencies before they become evident even without intstruments..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We open _InfluxDB_ and take a look at that data, which in this case _InfluxDB_ shows by default with _mean_ aggregation filter:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/015_DashT_LineChart_STW_default_aggr_mean.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "How does the raw data looks like? :Let's remove the _mean_ filter:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/015_DashT_LineChart_STW_raw_data.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What about applying [Moving Average](https://en.wikipedia.org/wiki/Moving_average)?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/020_DashT_LineChart_STW_Influx_mv_avg_20.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks much better." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, if we could just read that back to the _DashT_ dashboard... No problem!" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. index::\n", " single: Line Chart; Set up" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setting up" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Line Chart instrument is set up like other _DashT_ network augmented instruments, by adding it from the _Preferences_ menu into a Dashboard instrument pane:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/005_DashT_LineChart_adding_pane_instru.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Selecting the data source is like with an [EngineDJG](../enginedjg/enginedjg.ipynb#Subscribe-to-data), by subscription. Only that we do not subscribe to any data which is coming in, but to the data which is sent into the [InfluxDB](../influxdb/influxdb.ipynb#Introduction) time-series database by [InfluxDB Out](../idbout/idbout.ipynb#HTTP-Streamout) using HTTP protocol. Only this way one has some data in the database which can be read back." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The instrument is listening, for a while the data which is effectively sent to the database and let you select one of those." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ">**NOTE**: The below example works out of box so you are not necessarily required to read the description how it is done. But if you want to make changes it is required for understanding where the settings are coming from." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to be able to display something reasonably well, the _DashT Line Chart_ needs still to know about how you want that data being displayed - _InfluxDB_ does not, for example store the units of the values." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "_DashT Line Chart_ gets the default values for display formatting from the common configuration file, in this case these are the settings out of the box:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", " {\n", " version : 1,\n", " path : 'navigation.speedThroughWater',\n", " title : 'STW',\n", " symbol : '',\n", " unit : 'kn',\n", " display : 'chart',\n", " decimals : 2,\n", " minval : 0,\n", " loalert : 0,\n", " hialert : 0,\n", " maxval : 30,\n", " multiplier : 1,\n", " divider : 1,\n", " offset : 0,\n", " dbfunc : 'movingAverage(n: 20)',\n", " dbnum : 0,\n", " wrnmsg : false\n", " },\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare this to the settings in the _InfluxDB Out_ configuration file, in:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Windows**: `C:\\ProgramData\\opencpn\\plugins\\dashboard_tactics_pi\\streamout_http.json`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Linux**: `~/.opencpnplugins/dashboard_tactics_pi/streamout_http.json`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", " {\n", " \"sentence\" : \"OCPN_DBP_STC_STW\",\n", " \"mask\" : 4,\n", " \"store\" : true,\n", " \"interval\" : 1,\n", " \"measurement\" : \"navigation\",\n", " \"prop1\" : \"\",\n", " \"prop2\" : \"\",\n", " \"prop3\" : \"\",\n", " \"field1\" : \"speedThroughWater\",\n", " \"field2\" : \"\",\n", " \"field3\" : \"\",\n", " \"skpathe\" : \"navigation.speedThroughWater\"\n", " },\n", "\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The database streaming configuration sets up database schema, only addressing the data storage breakdown. In addition it defines - internally to _DashT_, not in the database - a Signal K data compatible key to make association with the database schema keys. But it does define in any way what is the unit of the data (knots in our case) or how do you want to call it (STW)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ">**NOTE**: [Signal K In](../signalk/signalk.ipynb#Signal-K-In) is not required as the data source, it can be also [NMEA-0183](../nmea0183data.ipynb#NMEA-0183-Data), it is only that a Signal K data key is used to identify the database schema used to store it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The _DashT Line Chart_ configuration file is shared with other similar insturments. It is located in these folders, after installation:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Windows**:\n", "```\n", "\\Users\\Public\\DashT\\www\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Linux**:\n", "```\n", "/usr/share/opencpn/plugins/dashboard_tactics_pi/data/instrujs/www/\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It contains instructions how it can be modified and how the instruments are told to take into account your changes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here as some interesting configuration values in our use case:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "dbfunc : 'movingAverage(n: 20)',\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can add a database function to the inquiry for data base data. In this case the database inquiry is build using the database schema and this string is added to the inquiry, and the resulting datapoints are returned with applied moving average function where `n=20` (see the above screenshot from the InfluxDB, it is exactly the same line we add). The presence of a database function is shown with a symbol `fn()` next to the data title." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "decimals : 2,\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default one decimal is used but in this case where we use averaging function, it is better to use two decimals. This way, the line chart is moving to the right direction continuously, otherwise the rounding of the values will make line being stable for a while, then jumping to the next decimal, etc. But if your values are two digit values by default, then one decimal is certainly enough. Please feel free to experiment to find a setting which works best with your data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So finally, here's the result (out of the box):" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/010_DashT_LineChart_STW_sliding_avg.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pretty cool!" ] }, { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. index::\n", " single: Line Chart; Numerical" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numerical values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[(zoom)](img/025_DashT_LineChart_histo-numerical_values.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is possible to read the numerical value of the historical data - the value in the header is the latest received value." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Place the mouse cursor over the bottom part of the graph and move it from left to right. Above the cursor one can observe the numerical value of each data point - in this example they are averaged values returned by the database function." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.2" } }, "nbformat": 4, "nbformat_minor": 4 }