 So, I'm Kai, I organized the Bay Area D3 user group with a couple friends. We all sort of organized it off the D3 mailing list. And I'm a design technologist at Stamen Design. And I have some, I don't have slides because I am going to sort of open these interactive examples and play with them and talk about them. But the links are at bl.ocks.org-syntagmatic, which is my GitHub username. And it's this first BIDS data science lecture notes. I have a couple projects on here that you could explore. But really, I just kind of want to get into D3 and what it's all about and how you can use it to visualize, especially in this talk, multidimensional data. So data where you have more than three dimensions or attributes on each data point. So really quick, let me just give a couple D3 resources because D3 is just a sort of many things. It's a JavaScript library. It's also kind of this, oh, hold on, we'll, we'll enable it, testing, testing, testing, no, testing, testing, okay, great. So D3 is, well D3 was created by Mike Bosak and I will talk about sort of my progression through one visualization, which goes back to ProtoViz, which was the sort of predecessor framework to D3. And ProtoViz is sort of inspired by GGplot, if you are familiar with R. So Mike Bosak is a creator. He's sort of, I think, been many years of kind of distilling just his, his insight into how browsers work and how to create interactive visualization in the browser. He's, there's dozens of interactive examples on this first link. Many of these are essays designed for people learning interactive visualization. So they're pedagogical examples. Some of them are articles that were published in the New York Times, where he works. He has a huge example, a huge sort of gallery of very simple examples. He created the service blocks.org, which lets you post GitHub gist, which is, they're just little simple, little HTML files. And these are also just simple examples that are designed to showcase one or several techniques. Almost all of them use D3, and you can kind of, the way I encourage people to learn is sort of browse this and find something you're interested in and sort of bring it closer to your data or change it in some way that you find interesting. There are examples of interesting geometries and topologies, force layouts, hierarchical layouts, dendrograms, tree maps, parallel coordinates, which I will talk about. All kinds of labeling techniques, cartographic techniques. It's just a really incredible body of work. Yeah. Some people say D3 is too much, they can't make it all in, and it has a complicated, Christian style. Do you use a simple subset of it, or do you use... Yeah, you'll always be using a subset of it. It is incredibly hard to learn the whole thing at once. So that's why I sort of encourage people to find just one example that they're interested in and really understand how that one example works and try to change parts of it, because you really have to learn it a bit at a time. Because there's all these geographic components, and cartography has its own challenges, and there's all kinds of D3 components to deal with those challenges. But if you're making a scatter plot, which is... A scatter plot is kind of... I'll talk about scatter plots in a moment. It's sort of the basic thing that's really easy to do with D3, and you won't need all that. You won't need a force layout or dendrograms. It does have a steep learning curve though, I would say. So it's not a... You won't pick it up and just sort of be making these things immediately. There is sort of a learning curve. So in the second half of this presentation, sort of after a break, I'll go through some examples and show you some of the work I've done with Michelle and Faulk on Ecoengine. And then in the second half, sort of build an example from Scratch. When I do that, I'll talk a little bit about sort of the specifics of D3. Yeah, feel free to ask a question anytime. So there's tons of examples here, and we will come back to this page several times over the course of this talk. Another collaborator on D3, especially on D3.geo and some of the more sophisticated layouts and projections that D3 has available is Jason Davies. He has just some incredible examples. This is a spherical Voronoi. So this is the globe, and these are Voronoi cells for airports. So this is a cell where LF Wade International Airport is the closest airport to every point in this cell. And Voronoi is normally on sort of just a flat surface. So this is on a spherical geometry. There is a big list of D3 examples that Christophe Vieux has made. There are literally thousands of examples. So Mike Basek has created on his own hundreds. Probably closer, probably more than a thousand. But hundreds and hundreds of examples. And if you include the whole community collectively, we have created thousands and thousands of examples, literally thousands. So on this page, there's 2,000. I think there's an updated list somewhere because I know the number for this list should be closer to 3,000. Obviously, I'm not gonna get to it all in this talk. I'm gonna take a really specific sort of approach oriented around multidimensional data. So a really nice multidimensional visualization. Now audio, great. This is the world distribution of income of people. This is Han's wrestling plot. So let me skip ahead. He did this wonderful talk in 2007. It's wonderful head talk where he was looking at different demographic properties of countries and comparing sort of fertility rates and life expectancy and female literacy across various nations and how that's changed from the 1960s into the modern era. And it's the sort of animated bubble plot. So time is encoded as an animation in this plot. And it encodes several dimensions of data. So we have a scatter plot we can pick on the X and Y axis, two dimensions. And so you could put life expectancy and fertility rate. And then we have the size of these bubbles. So normal scatter plot, they're just sort of equally sized marks. In this one, these bubbles are sized based on the population of the country or continent. The color is the continent, so that's sort of a fourth encoding. And then time encodes the fifth dimension, which is the change over time. So it's, and there's a D3 example of exactly this type of visualization. It's not labeled super well. So they get sort of technical here when we're talking about using D3. Let's just see where my time is at. The way that it works is you take a data structure. So let's say you have a CSV file, a table. And you bind, so there's many ways to do it. But this is sort of what's happening here. You bind a row of the data to HTML elements. So elements that are in a web document. So in this case, we're using SVG, if we sort of inspect this page here. SVG in every country is a circle element. So the data is bound to that element, all of the properties of that data. It's the life expectancy in years for every year. And the population and all these things change over time. And so D3 gives you a lot of tools for these kinds of animated transitions and specifying how the visual encoding come out. The visual encoding actually come from SVG, which is scalable vector graphics. So it's kind of a, it's its own sort of graphic technology. There's also HTML5 canvas and normal HTML and WebGL. There's various graphic technologies you can use in the browser. And most examples in D3 are SVG. So it's really oriented around that. So you're binding this data to these elements and then changing some aspect of the visualization using quantitative scale. So I use a more, what I consider consistent sort of way to visualize multidimensional data. So that was up to five dimensions. And once you get past five, it gets harder and harder to add more. If you try to put seven in a visualization like that, you really start, you've already used like the two sort of spatial dimensions in the screen. And you've got color and size and you can get creative about it. But why I came to D3 was this visualization. Yeah, it is, yes, you are not D3 is generates that for you. So in the second half of, I don't want to dig too much in the code here, because you can really sort of spend a lot of time on the details. But it does, that's absolutely how it works. So it's generating SVG elements. Okay, so parallel coordinates, this is sort of a case study. So this is a specific visualization and it's one that I've sort of taken and extended and it's very useful for multidimensional visualization. How it works is zoom in as much as we can here. Is each of the dimensions in your data set become these parallel axes. So these are all cars in this parallel coordinates and every line going across. Let me see if I can find a single one. So every line going across is a car with its various attributes. So this car has eight cylinders. It weighs about 5,000 pounds. It has all these properties and it's kind of a multidimensional scatter plot. So it's a way to, so you could add as many dimensions as you want. And every new dimension, dimensions don't have to be the same units. We have horsepower, seconds, miles per gallon. In fact, every unit in this visualization is different, time, number of cylinders. And the advantage to this technique is, okay, and then we also have these range filters. So on each of these dimensions we can put this range filter to drill into the data. Because up here it's sort of a cluttered mess, but being able to sort of drill in and see something specific is sort of the power. The interactive power of this technique. And the reason we plot them all as lines, rather than bars, is just so we can overlay them and see trends when there's a lot of data. So protoviz, as I said, was the, this is the precursor to D3. It was based on this idea of visual marks as the unit. So there are these marks and the marks then generate SVG. The different thing about D3 is that it doesn't have sort of this concept of visual encodings as the primary thing. It just lets you access HTML directly. So really any web technology, which is, I mean, that's its own huge sort of organic thing, all the web technologies that are available, but you can access them all with D3. And it makes it easier to do interactive transitions, sort of novel techniques. So Mike ported parallel coordinates to D3, it's the same visualization. And this is sort of what I started with. I took it and applied it to the USDA nutrient data set. So this is a data set. I'm gonna zoom in so you can read these labels a little bit. See if I refresh the page if it lays out well. So this is a data set curated by USDA. It has about 8,000 foods in it. And this is a subset of the data and it's a subset in two ways. So the actual data set has about 8,000 foods in it. And this is only 1,000 foods, roughly. And the actual data set has 150 dimensions. And this is only 12 or 14 or something. So in a moment, I sort of iterated on this to show the entire data set. But this was the first one I built and I'm trying to sort of go chronologically here. So let's grab a single food. So here we have potato sticks, they're snacks. And we read the visualization the exact same way. So it's got, we go across here and wherever this line hits these axes, that's the value in this data table below. So a table table below is super valuable just to be able to see the contents of what you're interacting with. So I spent some time with this visualization. At one point, I ported it to HTML5 Canvas, which is this example to be able to render more data. There are some performance challenges with D3 when you're trying to plot a lot of data and it's not that fun to talk about because it is sort of just sort of working around the fact that some stuff happens to be slow. But this is the way I could show the entire data set. And I just want to show sort of the big example of when you have a lot of dimensions in your data. So this is one where I used a fisheye distortion, let me turn off the distortion here. So this is almost the entire USDA nutrient database without some dehydrated spices because they were sort of outliers in the data. This is all per 100 grams of food. If I did it per serving size, I think they wouldn't be outliers. But per 100 grams of food, like a spice is an incredibly dense nutrient packet of nutrients. So without any distortion, this graph is, let me show the ticks. So this is the graph with all the ticks and labels and it's just a total mess. But it's interactively at this distortion and it sort of just peels apart. How the fisheye distortion works is kind of gives you this sort of Rolodex thing where you can zoom into a particular area. And then the interaction that I added to make it usable is you can click on a food and the dimensions reorder themselves. So that the scaled Y value of this food is always decreasing. So here we have beef and it's got, you can't read water here. This beef has 60 grams of water in it, 2.2 grams of lysine. Bunch of amino acids. We had the ticks here. This is all just in the browser all happening here. So, yeah. Roughly, how many do you commit for 40 hours? That is a good question. Maybe six or seven, but spread out over a couple of years. It's sort of my garden, I go to work on this every once in a while. In the future, I'd like actually to, as I said, make it all scale to serving size. And then I don't represent null data very well. So I'd like to get better at representing null data. Because it's a fairly sparse data set. There's a lot of, if we go over here, there's a lot of specialized fats. And so USD doesn't collect data on those fats for every food. There's interesting foods in here. There's like, I think there may be walrus, here we go, walrus meat. Ethnic foods are like a lot of Alaskan native foods. So there's also various whales, beluga whale oil, flipper and liver and stuff. But this is a technique, is parallel coordinates. So in this idea of D3, just sort of connecting back to D3, kind of the element we're working with that we're binding the data to are these lines that would go across these polylines. And the attribute, the visual attribute is at each dimension, it's where it intersects. So if you're interested in using D3, I've turned this into a library that sort of works more generically with just sort of lots of types of data. You can drop in a CSV file and it should sort of work. So it's kind of this reusable chart style. And it's a good place just to sort of explore what is in your data that might be an interesting visual encoding to make some other type of visualization. Unless they sort of to connect it back to what I want to talk about is how I used D3 to collaborate with people here at Berkeley on the Ecoengine API, which is a collection of observations sort of in an API that unifies them by space and time so you can query using these sort of range filters. So dimensions of the data here, we have observation type, country begin and end date, which actually, if you see this pattern sort of these lines that suggest that they're strongly linear related, actually these two dimensions are identical except for these outliers right here. So that's the idea. So let me show you some Ecoengine examples. So each datum is a, let's see, these are checklists, let me run a query here. So in general, the datum is a specimen observation. It's got a scientific name, a country. Sometimes it has a geo-coordinate and it has a time that the observation was made. And so with Stamen and Berkeley, we made sort of these tools. This is with Leaflet to explore these specimen observations. So one of the issues we ran up against sort of in making this exploration tool. And that we use a D3 technique to sort of start creating a solution for is that when you plot these sort of marks in Leaflet, they can end up on top of each other. So we have this sort of perceptual error, which is this error of occlusion. Because we have just a bunch of circles and they have, there's no way to see behind of them. You could add some opacity, there are some tricks you could do. But it's hard to tell the density of, I mean you can tell that they're dense here. But exactly how dense, that's the question. Cuz we're trying to sort of be as quantitatively accurate as we can in visualization. So some techniques that, sorry, Leaflet is a slippy map, sort of tool. It's a slippy map, so it's slippy in that you can sort of slip around like this. So Leaflet is generally always on a Mercator projection. Okay, so I'll take a short sidetrack into D3.geo while we're on Leaflet. So if we zoom out all the way here, so you see I always like to sort of scroll down here just to see how sort of grotesquely distorted Antarctica is. So Antarctica is just sort of like pinned like a frog to the bottom of the map. I mean Antarctica, right, if you saw it from space it doesn't look like that. And there's no way to change the way it looks really in Leaflet. It's just like that, it's the Mercator projection. So D3.geo which is a fairly, I mean it has its own sort of learning curve. See if I can find a transitions example here. Allows for dynamic projections. So here, so what Leaflet does is it's pulling tile layers. So it's pulling actual raster images, PNGs off of a server that have been pre-rendered for that location. So we've got the streets of London. And as you zoom in it gives you perhaps tiles with more detail. And it sort of fills them out as squares. And as you slip around it knows which squares it needs to get and puts the squares. With D3 we can pass in the geometry as data. So here the countries are a format called GeoJSON similar to a shape file. There seems to be some bug in the transition here. Some of the lines get a little weird. It could have been done using D3.geo. And in fact I will show a couple examples that we're done with D3.geo. Yeah. I just want to say one sentence about this. And that is if you see this for the first time and you go, that's impossible. I've never seen anyone else do that. You're right. It's very, very difficult. It's created with quite a stir when you publish it. And the point is that mathematically when you move from one projection to another or within some projections you get these startling screens. And what you're doing is there's a second set in the back that is moving out of the screen and then taking the pixels that we show on the screen. And Mike Bossack gave a talk about how you recently, or whoever did that. They really collaborated together on this. Yeah, yeah. They gave a talk about it because this is very startling and some people may be seeing it over time. I mean they spent probably a year and a half really sort of innovating on D3.geo. D3 always had geographic sort of mapping capabilities. Trying to find the simplification. But there were all kinds of techniques that they created to sort of... I mean there's all kinds of geographic problems with projecting a sphere. One of the things they solved was just sort of rendering the correct level of detail when you have a shape file where maybe the coastline is just way too detailed. And if the detail is smaller than a pixel it's pointless to render that detail. So this is just one example. It's a line simplification algorithm that just simplifies geometry and compresses it. So this geometry, it looks roughly the same as this. It loses quite a bit of detail. But if it was zoomed out it would be okay and it's only 1.5% the size. So there's all kinds of things like that. I mean lots of innovative things that they've done. So this is an example with D3.geo. This is just the Albers projection. So it's not actually that different than Mercator. And it's not interactive. But what I used here was the D3.hexbin plug-in. So let me just have that here. So again I think it's all about sort of reducing the error in your representation. So one type of error that we were just sort of talking about is projection error. The way that geographic projections distort angles and areas. When you are talked about areas of occlusion, when you just start sort of plotting points and they end up on top of each other really telling how many are there. Binning is a way to sort of accurately represent the quantity of data in a particular cell. A problem with square bins is that square bins are not sort of symmetric in terms of their adjacencies. So there's four squares that are close to each square. And then they're adjacent to eight squares, but four are on a diagonal and four are right next to each other. So they have this sort of lack of symmetry. And hexagons have a symmetry of adjacency. And they just look cool. So I decided to try to use them with eco-engine. So in this example, we just have, I got all of the observations that were geocoded of western fence lizards and dusky-footed wood rats. And we're just interested in the co-occurrence of species. And so I worked from Mike's Bivariate Hexbin example to create this. And sort of the only interaction here is that you can toggle on and off these layers. And when you toggle on and off these layers, it's actually smoothly transitioning all of the hexagons. It's not just swapping back and forth between two layers or having, there's not just two layers that are on top of each other. It's actually sort of combining the data and there's a color scale sort of shows the co-occurrence. So it's actually gray here. So you can see these ones when we just have wood rats on. This cell is red and we turn on lizards as well. The cell turns gray. So that's just sort of a simple example application of this technique. A couple others that we did. And these ones may take a while to load. So I have some screenshots if they don't load. Okay, let me just go to my screenshots. So these are, how big is the co-engine? Yeah, so this is one that's on and on traditional. It's on a non-mercated projection and it should be loading. Can I not change my, here we go. Should be loading here. So here's the first about 3,000 observations. But I just let it run for a little while and got 100,000 observations because they're just curious where in the world eco-engine observations end up. And I found these, I think these are fish observations just sort of around Antarctica. And they create this nice arc in this projection, which right in a mercator projection would sort of be, sort of deformed into this kind of clump. And so that's one possibility. This is from the Arctic, so this is Antarctica. This is the Arctic and it looks a little different. There's a huge sampling bias in California, of course, because, so another technique we tried out was this small multiples. So a lot of times when people think of maps, they think of these sort of full screen maps and overlaid layers. So another technique in multi-dimensional visualization is you use simple visualizations, but you show many of them side by side to invite comparison. So in this case we have quarkus genus, oak trees, and there's a great sort of biodiversity, many different species that all overlap in California. And so you could sort of see the differences. We're using these little hexpins and you can't really see the outline of California. This is the California coast right along here. Here's another, so this is more, these aren't really range maps. These are just kind of information richness in the API. So if you search these in the API, these are the results you get. So San Francisco is up here in LA, is down here. Yeah. So when I made this, I did add one for searching data. So the quarkus one actually has a secret, oh, and this dusky-footed wood rats over decades, it's just an example of small multiples. So small multiples you can get creative about which one is, and so in this case, instead of splitting it out by species, it's the same species over and over again, but split out by time to see a temporal distribution. So to answer your question, there is a secret search on the quarkus page. You can put in a search term here, what's something you could search from Ecoengine. So we can put Tariqa and split it by scientific name. Hopefully it'll load with some haste. I hope I didn't have, let's see if I'm getting an error here. I'm not, so I'm just waiting. This is actually from the Ecoengine API, which Fock built. Yeah, so in this case, and why these sort of take a little while to load, we're getting a page of data from the Ecoengine API. So I will show you exactly what that looks like. It looks like, and in fact we can run that exact, let's just run that query on the Ecoengine API. So the way the Ecoengine API works is it just takes these query parameters in the URL. And so we can put Tariqa query here. And you get back a JSON, JavaScript, object notation, data structure. It gives you the counts of the number of observations that are in the Ecoengine API, so 11,000. And then gives you an array of results. Each one of these results is an observation. And then what's happening in these hexagon examples, so it is loading, maybe if we come back to it in a second it'll load up a little bit. So what's happening in the hexagon examples is it's then doing the hexagonal binning in the browser and sizing the hexagons based on the number of observations at that location. It is. Yes, you're getting data and it looks exactly, it is this data. Yes. I noticed there's a geojson entry there. Are you actually using geojson, you know, probably with, say, some of the other geopitons or geosalicy? Are you, you take the geojson itself and move that around as it's own thing? Right, that's what's happening when in that example with leaflet. So that, so this one page, hopefully I didn't close it. So in this one page, actually this one just happens to be a build almost all with v3, but this map is leaflet and it uses geojson in sort of a kind of standard. Did you have to massage it when you passed the data or did it just work, what you got to pass? I'm sure I had to massage it. I don't remember exactly what. That's why I'm trying to get out of here. There is a lot of data massaging and it's an unglamorous part of data science and visualization but it is an important part because it's normally quite rare that the data is in exactly the format you need. So those were a couple of techniques that were applied, right exactly. So I guess, so I would say, so those are just a couple examples from this huge page of examples that I worked from to create these plots and ecoengine and so d3 is just incredibly rich in the number of techniques that have been demonstrated to create visualizations that have minimal error if you're willing to go out and find all of the techniques to minimize the error in your representation and also to sort of encode multi-dimensional data in many ways, whether it's with small multiples or parallel coordinates or another technique is linked visualization. So actually, I go back to my blocks here. So in this example, these bar charts below just the distribution of selected foods and so as I interact with this chart, this linked visualization provides a little extra context and so d3 is very good about it's tricky to do. It's not, it just doesn't come out of the box. You have to figure out how it works. But once you figure it out, it is easy to create this kind of linked views to take advantage of the strengths of two visualizations that whether it's a, could be a scatter plot in a map to understand the relation of the quantitative data with the spatial relationship the data contains. And so that's it. That's the sort of a brief overview of how to use d3 to visualize multi-dimensional data. So take a couple of questions if anyone needs to go ahead and then I will do a, in the second half I'm gonna do an example from scratch. And so the DOM is the document object model. So on a web website. Then it can be used to create and do all the things without even getting to traffic and all the stuff so that you know the tables or normally, like all of these, so I'm not gonna say like normally, it's out of the DOM-related actions, but what did you do in d3? And then you have all these crazy, graphic related maps that put your DOM elements in that way so that you can see basically two things that come together. And there's some purely functional stuff that it has which are just straight up data transformations and things like layouts, forced layouts and geographic projections are exactly that. A geographic projection is just a function that takes a longitude latitude pair and gives you an X, Y coordinate to plot that point on the screen. Yeah. I'd say that I'll be on top of that. I think it's a good solution. There's only just that question in life and I put the truth on to a lot of stuff or is computation intensive on the browser, low time, do you think that's presented to me? I mean, so in my work, I'm always super interested in speeding things up so that it is sort of performative. So an example like this is loading 8,000 points across the 16th dimensions and I have some techniques that you can find if you Google it's for sort of this progressive loading. So it throws all the data on a stack and then renders it in chunks and it's just sort of an easy way just to render a bunch of data. It can render a couple hundred thousand data points no problem and it works for any, it works for a scatter plot or a geographic map. There's this sort of mathematical thing with D3. Once you figure it out, you figure out that techniques can sort of be recombined and applied in different ways and that takes some intuition that just comes with learning it. I would say if you, it's really about building custom sort of visualizations and representation. So if you need something and there's not a tool out there for it, D3 is a great tool kit to build that yourself. If there are good tools for working with it and you really just, you need a visualization tool to quickly explore the data, it might take a long time to sort of learn D3 and there is quite a significant learning curve. And so I think it's worth doing though because it unlocks a lot of functionality that you can apply to your work. There's a whole other way around, though. I would say it is the de facto sort of visualization community just in terms of the quantity and quality of examples and people in the community. I mean, I would say Mike and Jason really are sort of at the forefront of the community and then there are hundreds of people like me who dabble and use it in our work. I was just showing some examples of Sarah Quigley, for example, who works at the university and does a lot of work with Sankey diagrams, which are another excellent visualization. They're useful. So these data structures called trees, which are these hierarchies. A Sankey diagram is sort of a more, plots a more generic version of a tree. It can be a graph with sort of cyclic connections. So it could plot a tree. That is sort of a subset of what a Sankey could do. But it can also sort of show connections that, so this do has a financial block and there's two things that are problematic in this collection of cases where students have financial blocks and these two problematic things could both be solved by this one solution. So that's just an example of the Sankey diagram, actually. This is one of Mike's interactive essays is the Sankey diagram example. This one is about the quantity of energy flow between nodes in a network. So where energy is lost. So it looks like a lot of nuclear energy produces energy by thermal generation and a lot of it is lost to heat or whatever. And then looks like 40% of it makes it to the electricity grid and then some of it goes to district heating. Anyway, so Sarah Quigley is, and there weren't a lot of examples of Sankey diagrams but Sarah Quigley just wanted to make these Sankey diagrams to show sort of information about the student body at Berkeley. And so almost anyone who learns, you know, is trying to use the Sankey diagram eventually stumbles upon Sarah's work because it's just helpful to learn from a variety of examples from different people and especially well-designed examples like this one where the information is communicated effectively. I mean, that's what I really like about the community. Yeah. So Canvas has mouse events but the only thing you get are the XY coordinates. So a lot of times that is enough to create interactions. If you have projected the data in a way that is invertible. So this is a kind of mathy, nerdy thing. So here, so I do have several examples of Canvas interactions in my blocks. It's kind of one of my things. This is super nerdy but, so for selecting on a Canvas globe, this is a Canvas globe and when you hover over country it highlights the country and the globe is rotating and stuff and there is no, so this is only interesting to people who know a little bit about D3. There are no SVG elements there for mouse over events. So the trick in this visualization is that I've plotted, this should be a hidden, here just so I could talk about it. I've plotted all of the countries in an equi-rectangular projection, just a static equi-rectangular projection and I've given them all a different shade of red. So there's only 200 in some countries so they can all get one shade of red. And I have actually an object that can go from a shade of red to the country and know what country it is. So when I put the mouse anywhere here, what I do is I invert the projection and then find that point in the equi-rectangular projection and then see what color red that pixel is and then I know what country it is and I can highlight it in the map up here. So as I said, it's a mathematical thing and once you realize that any projection you can invert, you can go back to sort of the, you can sort of look up the source data. It's the same with bins. So hex bins, you can also look up which bin it's in. And then a more sophisticated technique actually is quad trees. So is this a quad tree example? These are minimum bounding boxes. Anyways, quad trees are a way to sort of spatially index the data to do a fast lookup. So you can quickly find what is the closest point to another point. So it's not necessary to use SVG to get interactions, but it does take more work. Here's a quad tree search. So this is finding I think the closest six or seven points and it's doing it algorithmically. And so this example down here, you can use this example, the algorithm in this example, super simple. There's actually a quad tree module and all you have to do is specify this visit function. And so there's examples of how to do it. Any other questions? Okay, cool. Let's take a short break and then try to build something from scratch from on the eco engine API. Let's say two, two, three minutes? Five minutes? We realize some people try to leave us through a flag, but if you want to stick around in a few minutes, you can show a demo of how you can do something like this. Thank you.