 I just want to, I just want to. Oh, it's live! Yay! Okay, it says broadcast on AIR's live. Welcome everyone to the latest, newest Boku on AIR. Today, our special guests are Irene, Rose, and Mike Panini. Hello. Hello. So, guys, what are we talking about today? Bananas, for sure. Yeah. Because they're pretty ready. And D3Chart. Yeah. So, D3Chart is a library that we released a couple weeks ago that sits on top of the JavaScript library D3JS, which is a library for creating visualizations in the browser. Yeah. And when we wrote D3Chart, it was because we've been writing a lot of charts in D3 and we found that we were either duplicating content or copy and pasting things and we're big fans of the sharing patterns that the D3 community established with things like blocks. But we really wanted to think of a way to integrate some other patterns into creating reusable charts and providing a framework that will allow people to do that more automatically. Yeah. So, yeah, blocks is pretty, blocks is really good and the creator of D3JS, Mike Bostock, has done a lot of work making, kind of developing a good ecosystem for his libraries where people can share their work and kind of surface it in a way that's much more tangible than just writing a letter chart. So, there's, when we mentioned blocks, we're talking about the service that he's created where you take your code that's in a, what's called a GitHub gist or their code snippets on GitHub and they usually comprise graphs of some sort or charts or graphs or visualizations really of any kind and generally that service, that GitHub gist services there just to share code and so with blocks, you can feed it in the URL of an arbitrary gist and it will generate a page. So, instead of looking at the code for a chart, you're looking at the actual chart on the browser. It's been incredibly useful for D3 because there are just so many wonderful APIs that aren't always easy to understand and so through the use of these examples, I feel like D3JS managed to really grow the community that's been working with it. There were a couple of questions actually I think about the, about the library on Google. I'm just going to pull them up and ask, and I guess I'll take this opportunity too to let you guys know that if you have questions as you're watching, you can ask on either the Google Plus page or also in our IRC network channel, what is it, it's pre-node and we are hashtag Voku. So, if you have questions for me, you might pop them there I suppose. But one question came from Mike Wolfgang, you guys know Wolfgang. He is asking about how D3Chart can help maintain data integrity while respecting memory support. So, maybe I'll throw that out there for you guys. I think that's a really important question test right now and actually the next release of D3Chart, which I'm super excited about, tackles this problem. And maybe I'll let Mike talk about how, but I'll just kind of talk a little bit about the general problem of when you write a reusable chart, presumably you don't really want to rely on your data being, you know, in a certain format necessarily. So, if let's say you have a bar chart, you want to be able to visualize, you know, data when it's called, when the property is called value versus when it's called number or whatnot, right, you really don't want to have to change the underlying code of the chart to be able to make that change. And so, that's been kind of an issue that came up as soon as people started writing these charts, including ourselves with D3Chart of how it is to tackle that problem. And one awesome thing that came out of the solution that Mike worked on is the data integrity question. Sure, yeah. So, just backing up a little bit, the whole, I guess the whole mindset behind having D3Chart as a library is just to better facilitate people being able to separate out the definition of a visualization or specifically the chart and the use of that chart so that other people can reuse it. And so, we did a lot of work making it so that you can kind of extend the chart and repurpose it however you want and kind of mix and match different charts. But, yeah, almost immediately after we released it, this point was raised about, as Irene was saying, the shape of your data. And so, you can read through the issue on our, on the GitHub project page. So, if you go to the GitHub.com slash Miso project slash D3.chart, then you'll be able to go to the issues and you'll see that a few weeks ago, again, Tom opened an issue about this very problem. And so, we had this very long discussion where I posted way, way too long comments about like all my, well, all the different concerns we have among them like Wolfgang's recognizing is the integrity of the data. Because what happens is that if you want to support this, this problem, or this use case, where your, a chart should be in, be able to vary independently of the kind of data you pass it. So, just like Irene was saying, just because I make my bar chart work on the value attribute, shouldn't be there, one has to change their data around so that it matches my expectations. There's a number of ways that you can support that. And depending on how you do it, you will be very CPU intensive, a very numbering intensive. And so, if you read through that issue, you can see kind of us hashing out the different solutions and the different approaches. So, what we've, what we decided on was using data attributes. And that, like Irene was saying, is coming out in version 0.2 soon, you know. But in ES5 or ECMAScript 5 supporting environments, we'll use getters. So, that basically it allows the chart consumer, the person that's actually displaying the chart to define the shape of their data. So, that doesn't matter however with the chart was defined and how, what its expectations are for the data. Is, when you consume the chart, you say, this is what my data is shaped like. And what we do is, we support basically at runtime making that translation, so that we don't have full copying of the data. We also don't modify the data in place. So, we maintain their integrity. Right. So, basically for every data point that comes through, we'll only take the attributes that the chart creator defined are necessary and allow you to basically then provide a mapping for us. And we're only going to give you the data point that has those required attributes. So, that if you have to modify them, put them through the three layout, attach new properties to them, you can go crazy and they will be modified. And that's really convenient because if you think about it, you might have multiple charts in D3. They're all based on the same data that might all have to go through a layout. So, for example, if you put them through a treat map layout, that puts X and Y values on your data points. But then you might put them through a whole different layout, right, like maybe a graph of some kind. And those also need to be set the same attribute. And so, it's kind of an added benefit that, you know, came out of this approach in that you can put the same data set in all these different reusable charts, and they won't modify that original data. And then just then to follow backs for older environments that aren't up to the latest standards or even like not really the latest anymore. But basically in IE8, we're working on supporting this without where you don't necessarily have these ES5 features like custom getters or custom accessors. And so in those cases, if you do want your charts to run IE8, then we do end up doing more of a copying operation because it's not really a clean review otherwise. But if you want to see that, I have an open pull request that I'm still adding stuff to that you can check out the kind of implementation that falls back in environments that don't support specifically object.define property. And we'd really love some feedback on this approach. It's part of why it hasn't been merged in yet. We're finishing it up, but also are trying it out and seeing how it fits because it is a pretty big change and we want to do it early so that chart creators can integrate that into their charts in the future. But it's also a pretty big change. And so we really love your feedback. So we love feedback on all our libraries and our code. So definitely get in touch with us if you have any thoughts. Guys, there were also a couple of questions that we could pull up about to go into the sidetrack conversation. But I guess to conclude the sidetrack conversation. Joseph had, let's see, I'll show you me. Hi, Joseph. I was curious to hear your thoughts on DC and JS and the potential to extend N2D3 charts to replicators in that library. No, they are not. You weren't immediately familiar with DC, JS, but dimensional charting library. How is DC charting to work with other tools out there? So I've seen DCJS and unfortunately, I haven't used it. So it's hard for me to speak exactly to its structure. But the general patterns in DC chart are such that it's really more of an organizational framework for the way that D3 already has you write your charts. It really just identifies certain patterns that are pretty common when you write straight up DC code and breaks it up into more local pieces that also then afford you things like extensibility or modularity and so on. And so as far as, you know, as far as we think of anything that you can do with D3, you can basically layer D3 chart on top and then use some of these other frameworks that I've played around with using D3 chart with 2JS, which is a new library that came out that has a certain primitive rendering functions that can proxy to both SVG and Canvas. So I've been kind of just trying some stuff out. But then it, you know, it works pretty great because D3 chart is really small. It doesn't end up adding so much, you know, that, you know, you can't sort of add kind of your own layer on top of it. But I don't know, what do you think, Mike? So it is 2JS? Does that work on top of D3? No, it's completely separate. But you've used D3 chart with 2JS? Yeah, I was just I was just amused with seeing if I could do some joint rendering. I mean, it's not ideal. It's still probably do it in D3. Because the things that I was doing is it's just so much easier to do SVG. But you can definitely. And I've seen people do interesting things with Canvas with D3. So I definitely want to try and do a Canvas based library chart with D3 chart. D3 chart chart. Yeah. Yeah. That's interesting. Yeah, I always I kind of thought that D3 chart was kind of heavily relying on D3. Oh, it still is. It has to be like you have to have D3 defined. So it fixes the D3 namespace as D3.chart. Yeah. And I'm not sure how I'd use it. I'd love D3 scales. I just every chart I've ever written now has to have a D3 scale, even if it's not a D3 chart, because they're so useful. So where's that? Yeah. Yeah. So for me, like most of the most of the valuing in D3 chart comes from its use explicitly D3 is we're trying to we just try to define API on top of D3 that kind of recognizes the common operations you do when you're making a chart and makes them more, I guess, repeatable. And so used on its own or with other libraries, I guess I mean, you can say that it's it brings something to the table. Yeah, I mean, it's still preferred to just use I mean, I don't have to use SVG, for example, it's just as easy to render things with the DOM, right? If you're building a tree map, for example, you're just painting a bunch of divs, you can absolutely position them and, you know, use the same XY values as style properties. And you have your tree map. That's an example of using a different render me still uses D3. So you could do that. Yeah, I mean, it does end up breaking the mold a little bit. And I do think that D3 chart is best suited when you're using it with straight up D3. But so for example, I'm, I'm working on a base from which I will then build my charts. So I have a D3 chart base, which is really just random things that I find, I, you know, kind of have patterns for and then basically, every time I build a new D3 chart, I can extend that base. Instead of, you know, copying and pasting it, for example, so I can see that becoming maybe a pattern for someone who wants to write something on top of D3 chart, like a collection of actual charts, right? Because D3 chart is not a chart collection library, or library charts, right? It's a framework for creating charts. Yeah. So there are no, there are no charts. There are no charts. I mean, people make charts, which is awesome. We list those on the site. If you go to me so project comm slash D3 dash chart slash charts, that HTML, you will see both the way for you to submit your chart, then also a listing of your chart. Could it be D3 dot chart? No, I couldn't. Yeah, just wasn't. It was looking for file called D3 that chart. Oh, yeah. So there's a dash in there. What do you use to certify? GitHub. Just the GH pages. It doesn't support dots in the file. I don't know. We should, we should investigate. We'll investigate. I mean, why don't we go right now? This is the perfect time. Yeah, guys, do you mind? Yeah, well, this bumble around GitHub pages for a while. When you get it, that looks good. Yeah, good job. Yeah. Yeah. So there are some. Yeah. So Josiah was asking if you guys were discussing the whole set of data watch cycle events, which I'm sure we can talk about this. It's kind of a secret. I'd rather not say it's very no, it's not that all of you. It's very personal. And I don't feel like only family and really close friends. But I talked about the life cycle events with it. Well, I guess we're all we're all family. Yeah, okay. We're the open web family. Okay. This is where we don't really hug. But now right now, because there are the nanocomps. Well, I like it there. Okay, fine. Whatever. I'm not going to tell you how to live. All right. D three dot char, right? Yes. Alright. Life cycle. Life cycle events. So what we recognize is that baseball, basically, we gave we gave this name life cycle best to a like common operation D three, whenever you're making visualizations. And that basically, you D three has this method called data. And this is the way by which you kind of bind your data to the nodes that you're generating. And again, because D three works over SVG and also overdone, we won't get more specific as to what kind of notes they are, they might be, you know, rex, they might be dense or whatever. But generally speaking, whenever you go to draw your chart, you, you feed it some data, and you end up calling this dot data method passing the data. And then that generates a different kind of a different kind of selection. So if you're used to work with jQuery, your use, you might be used to the idea of generally selecting elements from the DOM. Or if you're just used to working with DOM APIs, it could be as easy as, you know, document dot, get elements by class name, or might be document dot query selector off, or it could be in jQuery, dollar sign, div. And all these are different ways of different on a context of making selections of things that are in the DOM. And so generally, like you can have a static kind of selection, and you just use D three dot select, and then you pass it a selector. And so that works a lot like these are the methods I mentioned. But then when you have them data bound, things start to get a little bit a little bit more complex. Because in that case, D three starts to recognize that there when you bind things to data, there are some elements that well, it needs to create some elements. If there's new data coming in. So imagine you have a bar chart, when you first start off, you pass it like four numbers. And so it needs to create four will say, wrecked SVG wrecked elements for each one of those pieces of data. And then that it can do, you know, whatever you tell it to you to make them the right heights, they all represent the data. But then if you really do call dry, again, maybe what you want to do is instead of deleting all those things, and then doing four, or in whole new ones, or five new ones, you might want to just update the ones that are there, and maybe add a fifth one, if there's more data, and then maybe even remove the last one, if you've moved your data set. So basically, it's not just, it's not just for efficiency, although it is more efficient than tearing down the whole structure and rebuilding the end. But it's also so you have constant scenes that you can kind of animate things to change. Because if this if this slice of the bar chart represents the same data and that data is just shifted, then usually in your visualization, you want to see the same thing happen with the actual thing that's painted on the screen. And so when you make these selections with D3, it can be confusing because you'll have a selection that represents things that aren't actually there yet, because you have these entering nodes that, because you have new data in, but you haven't actually appended them to your container yet. And then you also have xing nodes, so you can make a different selection that describes all the elements that used to be bound to data no longer are bound. And then you also have these, then if it's neither one of those things, and they're considered updating. And so in those cases it's because the data isn't new, but it's changed or shifted positions. So working with D3 directly lets you do a lot of things with these different kind of selections, but it can be confusing to do that directly. And also it can lead to extensibility problems. Because it's not clear for other developers, when you set up your whole chain of like do this with the nodes that are just coming in and do this with the nodes that are updating, and do this other thing with the nodes that are leaving, all that ends up usually kind of sprawl out in one big function, and they're all chained together, and you're not sure where you're modifying. So what D3 chart attempts to do is to make those selections feel more like events. So even though they are just selections that generally happen once every time you draw, it kind of makes sense to think of them as events and we adopted the API from jQuery of binding to them like they're events. And so what this means is that you don't have to, as the producer of a chart, you don't have to worry about making these special selections for these of the elements that are entering, these are the ones that are updating, these are the ones that are exiting. Because we recognize the general structure, the repeated pattern through making a bunch of different kinds of charts, we were able to encapsulate that onto the library. So it does it for you, and instead it exposes these events, so that as a chart author, you're able to look into the events and say, okay, I have a chart, and whenever anyone calls draw and passes a data, this is the stuff that I want to happen and want to have happen for the new ones, and this is the stuff that I want to have happen for the updated ones, and this is the stuff that I want to have happening through the exiting ones. And this makes it a lot easier for people to write the charts because they don't have to repeat that kind of logic. It makes a lot easier for other people to read the charts, and also to modify them, because it's much clearer instead of, like I said, this long function that does all those things. You have more discrete functions that are targeted at doing those different behaviors for different parts of the events. And then finally, it makes it easier for people to extend the charts because they can say, well, okay, I have this chart that someone else has defined that says what should happen in a bar chart when something comes in. And I think that, in addition to how this bar chart works, when new data comes in, I also wanted to do something else. And so this is a way that people can do that kind of programmatically without having to download the source code and open up in the text editor and change around the code. They can just programmatically say use that chart, but also add this additional functionality. Yeah. So we have actually four basic events in D3 chart. We have the Enter, which is what happens to brand new data points that are coming in and new nodes are going to be created for. We have Update, which is what's going to happen to data points that have been updated. So there are already elements drawn for them. Then there's Exit, which is what's going to happen to data points that have left and the elements that now need to either leave or fade or however you want to react to them. Then we have a fourth one called Merge, which is not actually one that's an official D3 life cycle event, but we realize exists because what happens is first you basically execute whatever you want to do to the updating nodes. And then you do, and so you have that selection of elements. Those get updated and then you have things that you want to do to your brand new nodes, which is the entering nodes. And the moment you're done with those things, those basically become one. And now you can react to all of them in this merge event, which is pretty handy. So if you want to highlight updating versus new, then you want to do something to all of them together, which is basically everything on stage that has an Exit event. So that's a pretty useful one. And then you can also bind, the other thing that's neat is you can bind not just to those events, but you can actually bind to those events, the transitions of those events. So for example, if you have let's say a layer, we should talk about layers too. We'll do that in a bit. If you have let's say a bunch of rectangles and they represent your bar chart, and then on entering, you want to paint them green, well you can either define what should happen on an enter event, and just set the style fill to green, or you can actually bind to the enter colon transition, and you again do the exact same thing, you just say the style attribute to green, except it's actually going to animate. Because what we're passing in instead is actually the the transition call on that selection. So that's kind of neat because you it's really easy to animate some of those properties pretty quickly. Yeah, Tom had a couple of questions actually, and I guess I'll ask his second question first because it seems more relevant. He was curious if there was a built-in way. He asked the first question first. He did ask the first question first. I'm inverting this. You know better than Tom about this question. Listen, I'm not the emcee. I'll let you do your job, and I'll do mine. Yeah, sorry Tom. Thank you. It would be different if I won't check. Anyway, Tom would like to know if there's a built-in way to redraw a chart with the same data that was last passed to him. To redraw a chart with the same data that was last passed to him. So I don't think he's about a question. Was there like a proceeding question that might have given you a question? Oh, okay. So this is actually a common problem that we've thought about, and it actually comes up very frequently. If you want to make a chart that has, let's say, getters and setters that maybe modify its dimensions, for example. So let's say you've drawn a bar chart and you're making your site responsive in some form and you want to respond to a screen shrinking by shrinking your chart. What you want to do is then just have that chart redrawn that smaller space. And so a common pattern, and this isn't something that's built in, is that when you get your data, so the way that you even render anything is through this construct we call layers. And layers is just a way to aggregate elements that are logically connected and are going to be rendering themselves based on data. So in a bar chart, it may be rectangles, we may call them bars. In a pie chart, they may be pie slices, right? You know, however you want to call them. You might have multiples of them, you might have one. But when you define one of those, you basically pass it three things. You pass it what's called a data bind. You define a function on a property called data bind. And that takes in, that function takes in the data. That's the only place really where in your chart you're going to get to interface with the data. And that's the data that comes in directly from when you call that draw on the chart that you instantiated as a user. And so a common pattern there is to basically save that data onto a property of the chart. So maybe, you know, chart that data equals data and whatnot. And then inside of some of those gathering centers that could maybe modify the dimensions and so on, you just call this that draw with whatever saved on the data. It's not something that we've built in by default because we're not sure yet that this is the common and expected behavior, especially since we're not providing by default some of those gathers and centers. But we're very curious to see what patterns people will come up with to solve that problem. Yeah. Yeah, because right now basically a chart as defined really doesn't hold any references to your data. It kind of just passes it through transparently. And once you're done drawing, it doesn't care anymore. So it's basically your data comes in to draw when you call it and then it goes out again. And so we've we've thought about supporting like a redraw method or something like that that explicitly didn't take a an argument that date argument and just reuse the last one. That's kind of a more of a leap than we want to take just now such an early stage where we're kind of getting into the space of kind of managing your data on 40. So for now, this is something that's you can do is just takes a little bit of extra work you like I've been saying is just save a reference in in your data by method. And then you can define your own redraw method if you want. It just that just calls from the last the last value of the data. Well, well, I'm talking to say that that's right exactly because this case. So whoo, whoo, go you mine readers slash question readers plus plus one to the banana on the right. Plus one. But the second question, which was actually his first question is whether it's possible to refer to the super implementation of a method within an overriding information. So it. Yes. But it's named Dunder super double underscore super. We're not sure if that's if that's how we want to support that just. So for now we're kind of we kind of just we have it because it is we're using slightly a modified version of Backbone.js, the MVC framework. We're using a modified version of its extent method. And that's essentially if you look at their extent, that's exactly how they track that. And while that one doesn't actually use the double underscore super property, it just kind of keeps it. For all reasons for coffee script support, just odd. Yeah, if you want to hear a feel of being a troll, you can even open the issue saying, you know, let's get rid of this. But. But for us, we actually do use it because specifically for initialize. So every chart that's defined the three dot chart may optionally define initialize function. And this is again kind of a back bone ism, which is basically basically like a constructor that's that that works in terms of our kind of inheritance pattern that again comes from back in JS. So if you define initialize, then that code will be run whatever you you whatever you create a new instance of whatever chart. But in addition, if your chart happens to extend some other chart, that chart's initialize method. And so forth up the chain. So if that chart happened to be extended from a different chart, now it will be called and they'll be called actually in reverse order. So the oldest or the highest or the great great grandfather charts initialize is going to be called first and then on down until you're initialize is called. And so that that that behavior exists specifically for initialize because initialize is such an important method for creating instances of charts. And it's also one of the only methods that that may be shared by all the charts. And so if you were to realistically extend it, you generally depend on the logic that your base chart has put in initialize. And so. So what we're talking about right now, though, is is is kind of surfacing that suit that super property so that you're able to do the same thing with any with any arbitrary method. And that allowing that tends to tends to couple charts and also, well, it can be it can be it can be things more difficult to reason about. So for the time being, if a chart if a chart you're using defines a method that you also want to use, then I would recommend just meaning in your method is something different. So you don't essentially shadow the implementation of the method you want to call. And so that way your extended chart will define both these methods. But like I'm saying, we really kind of feedback. So hearing about use cases for this like super functionality really. Yeah, and it's a lot more unclear with methods that are not initialized, whether the intention was to go off the chain or that the intention is to override, right, which is why you know things like super exist in other languages, which allow you explicitly to indicate that within your chart if you want to. And so, you know, we're really curious to see if it's going to work out, if it's going to work that way, if it's going to become necessary, since we are already supporting, you know, just by doing that initialize the chain effectively much more than you normally get by just using standard extending and JavaScript. So I want just to worry. Right. And yeah, and just doing it automatically is you don't have to worry about it yourself. It's done for you. Right. This would probably be a great time to remind folks that, like, if they're implementing your chart and running into issues or patterns, it should be like letting us know in the book who IRC channels because we check out all the people. We're always there. Always there. Never leave. It's really weird. Yeah. It's been here for a hundred and thirty two days. Where else should they go to Irene, like, if they want to document some stuff because. Sure. Well, we have a lot of documentation for D3 chart and it's constantly growing. So the Wiki is very detailed and we've been putting a lot of content into it. Also, the ISO project website has an entire section dedicated D3 chart. And every time that someone runs into it would be like a tricky thing or maybe a certain pattern they've established, I try to write like a little tutorial for it. They're not really, you know, tutorials in the sense of what we're going to build something together, but they are effectively concepts because we're trying to avoid the case where, you know, if here's an API and you don't really know how to use it, we're just kind of want to tell you exactly how. You can use some of those things. So if there's, you know, maybe something that's unclear, definitely let us know and we'll be right about it or if it's a bigger question, you know, we write a lot on the book who blog. So if you haven't read every single one of Mike's posts, you really should because they're amazing and I love to read them twice or three times even. So we'd love to write, you know, more about it. So whenever people struggle with stuff, it gives us, you know, kind of impetus to keep going. So that's one. You can always ping us on Twitter, you know, we're pretty reachable that way. Yeah, you can call us. You can stalk us and show the house. Their phone numbers are 555. I would prefer no one stopped us. OK. That would be helpful for me. And just, just, oh, I'm I mean, mentioned the wiki and just to be a little more explicit, the wiki right is hosted on GitHub. And so if you go to github.com slash miso project slash d3.chart, you'll find the wiki there. And so that that wiki is also open, open to edits. So like most like any good wiki so that if you find a typo or something that's flamely, flamely long or maybe, you know, maybe you're just having a bad day and you just want to get some aggression out. You can edit and change things. We need more cats. Yeah, I don't know that our wiki has any cats. I don't know what the right number of cats are. Please don't put cats. Or, OK, you put one. Tasteful. Tasteful. One tasteful cat. One tasteful cat. Which one? It's not being so prescriptive. It might be two. But it needs to be tasteful. I don't care about numbers. They all have to be one photo, all the cats. All the tasteful. And of course, issues. I should also say that we love, like for us, issues aren't just, hey, we found a bug in G3 chart. For us, it's also a way to ask questions about how to do something and, you know, or if we want to ask for a feature or if something's confusing. Like that's really important payback for us because, you know, we've been so in it for so long. You know, we've been effectively trying to come up with the right answer for this problem for like close to a year, literally, since after MISA dataset was released, we started thinking about the problem and then eventually, you know, I had the privilege of having Mike join me and come up with amazing solutions to do it much better than what we're thinking about. So it's really exciting that it means that we've been thinking about this for a really long time. So fresh eyes are super useful. So I think we've been chatting for some time now. And there's like one question that's somewhat serious, but we'll see a softball. Do I need to take the banana costumes off? No. That's the second thing that we're going to have to address. And, you know, apparently there are some who don't appreciate the important role that the banana costumes really have played. Oh, do you know how to kick people from IRC? Yeah, let me just do the IRC. Tim, Brandon, you're done for money. Yeah. Love you, Tim. I want the softball question. Yeah. Do you want that one? Yeah. Oh, there. That one comes from Adam Highland and his question is whether you guys can either one of you have a cool, clever Nixon afford that you're supposed to. I've made a couple of fun ones that had, you know, it's really easy to add zoom behavior to D3. And I recently had to do it with a couple of charts and realized that that code was like super similar. And so I'm separating that into a mix-in. And then there's also been some tool to, I also wrote a quick tool to thing that I want to try and make a mix-in, because that's super useful. Tool tips. So I always throw those on stuff. So I'll probably have that as a mix-in out pretty soon. It's probably... Yeah. I have no practical experience with D3 charts. Basically, I just I sit in my ivory tower and I think about new features that the user might want and then I code them up and I really have lost touch with that. And then I make them feel bad for a while. Then I come out with demand. That's true. Like a jerk. Like a jerk. We have an awesome work. Like a... Like an awesome jerk. Like an awesome jerk. I'll take it. But yeah, if you guys want any mix-ins that would be useful to you, let us know. Five bucks. Five bucks. No. No. That's what open source is. Give you five bucks. No, I'm kidding. Five bucks. Four or five dollar donations. We haven't talked about mix-ins explicitly. So I'll say really quickly that mix-ins are a separate kind of take-on code sharing. So we've talked about inheritance and how you can define one chart in terms of another chart. So you take your tree diagrams and you make your terrible tree diagram. It just basically takes the same tree diagram and it makes everything black and you can't read anything or something. And so that's basically you're defining one chart in your extension. So that's why we call it extensions. But then mix-ins are more of a composition of multiple charts. And so basically you can define a chart in terms of many different charts. And so what this is useful for is if you want to make a chart from components that aren't necessarily charts in and of themselves. So in D3Chart, D3Chart's API still makes a lot of sense for defining a quote-unquote chart that's really nothing more than say like labels. And then maybe it's really nothing more than boxes. Maybe that one's nothing more than axes and axes. And so you can use the mix-ins to say, okay I found like these really cool components that in themselves aren't really useful but that I want to combine in my own way and make it to a chart. And if you go to the Bogu blog you can see an example of this where I take these popular D3JS chart examples. One is of a bar chart and one is of a chord diagram. And I mix them together to make a chart that really has no meaning or practical use that kind of looks neat. But it's awesome. So that's on the Bogu blog at a post called Exploring Readability with D3.js. Yeah. And Mike's done this amazing post by actually continuously reworking the code in different commits. And so not only can you read this great post but you can also basically follow the code along as it progresses. It's like the best use of GitHub commits I've ever seen. And there's just, well this I mean it's pretty good. Yeah. Well it was, I got really good at rebasing. He is our rebasing expert. Well I forgot like there's a typo for commits back. Make all those commits again in the meantime. It's an impressive effort. I'm glad that it's somebody for that. Well guys I think we've been chatting for almost 45 minutes now so we should probably wrap it up. They were never here. Cricket, cricket. And questions. I just made them. She's just humoring us. I'm trying to make things up for you. When do we get to turn on the birthday cake? Now is the agreement. We do this and then we get on. This laptop is even on. Yeah. This is actually a mirror. We've just been looking at ourselves the whole time. I'll do that too. I was the pretender So, I guess for you to just let everybody know, we do these hangouts on air, you know, every four or six weeks or so, and it's just typically a series of Bo Cooper's talking about things they're passionate about. In a hot air balloon. You know, and sometimes in costume, which I think brings up our- It's just our work clothes. We don't have them rain in my eyes. It's the open web uniform. Yeah. So, you guys can always talk to us in the go-to IRC channel over there all the time as we mentioned earlier. Any questions about JavaScript related or banana related, we're happy to answer. But, I think there are a couple of questions in the Google thing that you can get to, but we'll try and answer those in the comments on the Google event page. But, thanks everyone for watching. Thank you guys. We love you all. Bye now. Bye. Bye. Bye now. Bye now. Bye now.