UNPKG

signalk-polar-performance-plugin

Version:

A plugin that calculates performance information based on a (CSV) polar diagram.

250 lines (219 loc) 5.88 kB
<!DOCTYPE html> <html> <script type='text/javascript' src="./Chart.min.js"></script> <script type='text/javascript' src='/jquery/dist/jquery.min.js'></script> <title>Polar performance</title> <body style="background-color:#020202;"> <canvas id="myChart" style="width:100%;max-width:1200px"></canvas> <script> var polarSpeed, boatSpeed, TWA var myChart, chartData $.getJSON("/plugins/signalk-polar-performance-plugin/chartData", function(json) { // Add actual values dots json.datasets.unshift({ label: 'Polar Speed', backgroundColor: 'rgba(0,255,0,0.7)', borderColor: 'rgba(0,255,0,0.2)', borderWidth: 1, radius: 30, type: 'bubble', data: [ { y: 0, x: 0, r: 10 } ] }, { label: 'Boat Speed', backgroundColor: 'rgba(0,150,255,0.7)', borderColor: 'rgba(0,150,255,0.2)', borderWidth: 1, radius: 30, type: 'bubble', data: [ { y: 0, x: 0, r: 10 } ] }) chartData = json showChart(chartData) }) function showChart (data) { console.log(data) myChart = new Chart("myChart", { type: "scatter", data: data, options: { legend: { display: true, labels: { fontSize: 16, fontColor: 'white' } }, spanGaps: true, scales: { x: { type: 'linear', ticks: { color: 'white', font: { size: 14 } } }, y: { type: 'linear', ticks: { color: 'white', font: { size: 14 } } }, xAxes: [{ scaleLabel: { display: true, labelString: 'True wind angle (TWA)', fontColor: 'white', fontSize: 16 }, ticks: { display: true, fontColor: 'white', fontSize: 16, }, gridLines: { color: 'rgba(180,180,180,0.7)', lineWidth: 1 } }], yAxes: [{ scaleLabel: { display: true, labelString: 'Target boat speed (POL SPD)', fontColor: 'white', fontSize: 14 }, ticks: { display: true, fontColor: 'white', fontSize: 14, }, gridLines: { color: 'rgba(180,180,180,0.7)', lineWidth: 1 } }], }, tooltips: { enabled: true, callbacks: { label: function (tooltipItems, data) { console.log("tooltipItems: " + JSON.stringify(tooltipItems)) console.log("data: " + data) let label = tooltipItems.xLabel + "° " + tooltipItems.yLabel + " kts" return label } }, backgroundColor: '#666', titleFontSize: 18, titleFontColor: '#0066ff', bodyFontColor: '#ddd', bodyFontSize: 18, displayColors: false } } }) var ctx = document.getElementById("myChart") ctx.style.backgroundColor = 'rgba(0,0,0,0.8)' ctx.style.fontColor = 'white' } function connect () { console.log("connect()") ws = new WebSocket((window.location.protocol === 'https:' ? 'wss' : 'ws') + "://" + window.location.host + "/signalk/v1/stream?subscribe=none"); ws.onopen = function() { // Start listening for value updates startListeners(); ws.onmessage = function(event) { if (event.data.includes('signalk-server')) { welcomeMessage = event.data; console.log("Skipping welcome message: " + welcomeMessage) } else { handleData(JSON.parse(event.data)); } } ws.onclose = function() { console.log("WebSocket closed") setTimeout(connect, 500) } ws.onerror = function(err) { console.log("WebSocket connection error: " + err.message + " - closing connection"); setTimeout(connect, 500) } } } window.addEventListener('focus', function () { if (ws.readyState == 0) { console.log("Restarting websocket") connect() } }) function startListeners () { var paths = [{'path': 'environment.wind.angleTrueWaterDamped'}, {'path': 'performance.polarSpeed'}, {'path': 'performance.boatSpeedDamped'}] var subscriptionObject = { "context": "vessels.self", "policy" : "ideal", "minPeriod": 2000, "subscribe": paths } var subscriptionMessage = JSON.stringify(subscriptionObject); console.log("subscriptionMessage: " + subscriptionMessage); ws.send(subscriptionMessage); } function handleData (data) { if (typeof data.updates[0].meta != 'undefined') { return } var path = data.updates[0].values[0].path var value = data.updates[0].values[0].value if (path == 'performance.polarSpeed') { polarSpeed = roundDec(msToKts(value), 1) // console.log('polarSpeed set to %s', polarSpeed) chartData.datasets[0].data[0].y = polarSpeed } else if (path == 'environment.wind.angleTrueWaterDamped') { TWA = roundDec(Math.abs(radToDeg(value)),1) // console.log('TWA set to %s', TWA) chartData.datasets[0].data[0].x = TWA chartData.datasets[1].data[0].x = TWA } else if (path == 'performance.boatSpeedDamped') { boatSpeed = roundDec(msToKts(value),1) // console.log('boatSpeed set to %s', boatSpeed) chartData.datasets[1].data[0].y = boatSpeed } } connect() setInterval(updateChart, 300) function updateChart () { myChart.update() } function radToDeg(radians) { return radians * 180 / Math.PI } function msToKts(ms) { return ms * 1.94384 } function roundDec (value, decimals) { if (typeof value == 'undefined') { return undefined } else { value = Number(value.toFixed(decimals)) return value } } </script>