Visualizing the Signal Graph

Julia Allyce
Wireless Registry Engineering
5 min readJun 1, 2016

--

One of the big challenges I’ve had recently is simply explaining to people what we do at the Wireless Registry and why we do it. Plainly, we collect and analyze information about wireless signals. The signals are invisible to humans, and are not something we consider much beyond connecting to the internet — but this is the way our personal devices talk and identify with one another. From a device’s point of view the physical world is just a bunch of signals.

Recently, I was cleaning up my wifi networks. It was kinda nostalgic to go through all the remembered networks.

My favorite coffee shop in Denver, friends’ home wifi networks, a past business trip… Each of these wifi networks provide a small foot print of mine and my devices’ existence.

Signals around the office…

Beyond the networks and devices we connect to and know, there are all the other signals that our devices are constantly “sensing”. Especially in dense cities, there are signals everywhere: FitBits, phones, TVs, fridges, etc. These days, nearly everything and everyplace is emitting a signal. Even our water filters.

This is the space that we are working in at the Wireless Registry. We believe there is meaning and context to be inferred from all the devices and signals that coexist with us.

Until recently, this table to the left was how we were working with our data. This is just a small chunk of the signals seen in a single day by a single observer. In short, this was just terrible and difficult to digest. The problem is laid out, and I accepted the challenge!

Our first iteration of visualizing a single observer’s signals. Each circle represents a unique signal. The colors indicate the type of signal (bluetooth, BLE, or wifi). The size of the circle is the proximity, and the y-axis indicates the number of times a signal has been observed. The signals light up for each point in time they have been observed.

The first visualization we made was more of an experiment in looking at how an observer sees signals over time. You can immediately see when the observer is in areas of high signal density, and when they are seeing relatively few signals. Additionally, you begin to see patterns of signals that are regularly seen together. Still the visibility into the relationships between signals was not clear, and thus we began playing with D3 force layouts.

Our first force layout. 👶 Rendered with SVGs

A single observer’s data lends itself pretty well to these types of network visualizations. Despite having a high degree of nodes and edges, we avoid hairballs. Signals can only be observed within a certain proximity of the observer which results in clustered networks of data.

Left: An xfinitywifi hotspot seen between two clusters of signals. Right: Signals captured at DC’s Martin Luther King Memorial Library. Rendered with SVG.
A week of seen signals by our coworker, rendered with Pixi.js/WebGL

To bump up our data, and stress test our visualizations, we set our observer to capture signals about every minute of the day. In a 24 hour period our observer captured 36,668 data points for 1,228 unique signals. The final result is 52,102 links (or edges) between each of our signals. A week of data is 172,798 data points, 5,342 unique signals, and 318,237 links.

The observer in this case is one of our coworkers. His daily routine is basically commuting less than a mile from home to work. However, despite the lack of diversity in his daily routine, he has built a very rich signal graph.

Rendering this large chart was a big technical challenge. Standard D3 + SVGs maxed out at around 1,000 unique elements (nodes and edges), and forget about interacting with the visual. Inspired by Dominikus Baur’s talk from OpenVis 2016, I decided to try out WebGL, as my desperate tweet shows:

HELP ME PLEASE :[
Signals observed over time

A quick search for tools turned up very little, or at least nothing as fun, popular and easy to use as D3. Ultimately, I settled on a hybrid. I used the new D3 force library and Pixi.js as my rendering engine. (Shout out to Irene Ros for giving me a good starting point.)

The benefits of using WebGL are that you get access to the GPU for rendering your visuals, but all this power comes at a cost. WebGLs API is complex to say the least. Pixi does a good job of wrapping WebGL in an accessible library, and has a very active community (even though their forums remove line breaks from code snippets; Dear God whyyyyyy?). Additionally, it was easy to keep the work I had done already in D3, since the force layout calculations are independent from the UI rendering.

Exploring the Signal Graph

The end result: I went from rendering ~1000 elements (nodes and edges combined) with no interactivity, up to ~100,000 on my macbook pro with relatively responsive interaction. A machine with a better GPU would get more milage out of this.

Aside from switching to WebGL, we improved the performance by not rendering edges inside clusters until you click on a node that connects to the edge. This cut our edges rendered by ~60–70%.

Nodes: 5342 , Total Edges: 318237
Rendered Edges : 95108

Opportunities for further performance improvements:

  • Looking into how Pixi is rendering the lines. My understanding is that Pixi uses more expensive polygons instead of raw WebGL lines.
  • Using sprites for our nodes instead of circles.
  • Run the force layout calculations in a worker thread.
  • Abstracting out all the data normalization and edge calculations to a micro service. Right now this all happens in our client app.

Overall, for a tool to investigate our data, I am pretty happy with this. Using D3 + Pixi is a good compromise that lets me quickly implement a much faster version of our network visualization with out having to get too deep into WebGL.

The next steps are to move away from individual observer data and move into visualizing many observers at once. This will provide more meaning to signals that are seen together often, and a more complete picture of how our devices see the world.

--

--