Skip to content

Instantly share code, notes, and snippets.

@dreness
Created February 7, 2021 21:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dreness/51e557682d697c3cce4b832c8e1eebbc to your computer and use it in GitHub Desktop.
Save dreness/51e557682d697c3cce4b832c8e1eebbc to your computer and use it in GitHub Desktop.
Realtime graph from WebSocket data
#!/bin/zsh
D=$(date "+%Y-%m-%d")
#D=$(date "+%s")
ifstat -t -n -i en0 \
| sed -l '1d;2d' \
| while read -A IFSTAT
do
echo -n "{"
echo -n "\"Time\": \"${D} ${IFSTAT[1]}\", "
#echo -n "\"Time\": \"${IFSTAT[1]}\", "
echo -n "\"In\": ${IFSTAT[2]}, "
echo -n "\"Out\": ${IFSTAT[3]}"
echo "}"
done
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="plotly.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<div class="navbar"><span>Real-Time Chart with Plotly.js</span></div>
<div class="wrapper">
<div id="chart"></div>
<script>
buttonInfo = [
{"count": 30, "label": "30s", "step": "second", "stepmode": "todate"},
{"count": 60, "label": "1m", "step": "second", "stepmode": "todate"},
{"count": 300, "label": "5m", "step": "second", "stepmode": "todate"},
{"count": 900, "label": "15m", "step": "second", "stepmode": "todate"},
{"step": "all"}
];
var xaxisLayout = {
title: "Time",
showgrid: false,
zeroline: false,
type: "date",
rangeselector: {buttons: buttonInfo},
rangeslider: {},
};
var layout = {
title: "Bandwidth",
xaxis: xaxisLayout,
yaxis: {
title: "KB/s",
showline: false,
//autorange: true,
//fixedrange: false,
//min: 0
}};
var d = new Date();
var wantXrange;
function datestring() {
d.getFullYear() + "-" +
(d.getMonth()+1) + "-" +
("0" + d.getDate()).slice(-2) + " " +
("0" + d.getHours()).slice(-2) + ":" +
("0" + d.getMinutes()).slice(-2) + ":" +
("0" + d.getSeconds()).slice(-2);
};
startDate = datestring();
//console.log(startDate);
var trace1 = {
x:[startDate],
y:[0],
type: "scatter",
name: "In",
mode: "lines",
line: {color: "#00FF00"}
};
var trace2 = {
x:[startDate],
y:[0],
type: "scatter",
name: "Out",
mode: "lines",
line: {color: "#FF0000"}
};
var data = [trace1, trace2];
var mySocket = new WebSocket("ws://boop.local:80");
mySocket.onopen = function (event) {
mySocket.send("womp");
};
mySocket.onmessage = function (event) {
var msg = JSON.parse(event.data);
updateGraph(msg);
};
var config = {responsive: true}
Plotly.newPlot("chart", data, layout, config);
var cnt = 0;
function amax(arr) {
arr.reduce(function(a, b) {
return Math.max(a, b);
})};
function amin(arr) {
arr.reduce(function(a, b) {
return Math.min(a, b);
})};
myPlot = document.getElementById("chart")
buttons = [].slice.call(myPlot.getElementsByClassName("button"))
// keep track of the desired data window size
buttons.forEach(function (element, index){
element.addEventListener("click", function(){
if (d = buttonInfo[index]) {
//console.log("s", d.count);
wantXrange = d.count;
};
});
});
function updateGraph(data) {
Plotly.extendTraces("chart", {
y:[[data.In], [data.Out]],
x:[[data.Time], [data.Time]]
}, [0, 1]);
if (wantXrange) {
xlen = trace1.x.length;
if (wantXrange < xlen) {
layout.xaxis.range = [trace1.x[xlen-wantXrange], trace1.x.slice(-1)[0]];
var ymax = Math.max.apply(
null,
trace1.y.slice(-wantXrange).concat(trace2.y.slice(-wantXrange)));
//console.log("wantXrange <= xlen");
//console.log("ymax: ", ymax);
// FIXME: This doesn't work...?
layout.yaxis.range = [0, ymax];
Plotly.relayout("chart",layout);
} else {
layout.xaxis.range = [trace1.x[1], trace1.x.slice(-1)[0]];
//ymax = amax(trace1.y, trace2.y);
//console.log("wantXrange > xlen");
//layout.yaxis.range = [0, ymax];
};
};
};
</script>
</div>
</body>
</html>
@dreness
Copy link
Author

dreness commented Feb 7, 2021

❯ ls static
live-plotly.html	plotly.min.js

❯ websocketd --staticdir=static /Users/andre/bin/ifsocket
Sun, 07 Feb 2021 13:54:49 -0800 | INFO   | server     |  | Serving using application   : /Users/andre/bin/ifsocket 
Sun, 07 Feb 2021 13:54:49 -0800 | INFO   | server     |  | Serving static content from : static
Sun, 07 Feb 2021 13:54:49 -0800 | INFO   | server     |  | Starting WebSocket server   : ws://boop.local:80/
Sun, 07 Feb 2021 13:54:49 -0800 | INFO   | server     |  | Serving CGI or static files : http://boop.local:80/

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment