Check out a free preview of the full Data Visualization for React Developers course
The "Brush Exercise & Solution" Lesson is part of the full, Data Visualization for React Developers course featured in this preview video. Here's what you'd learn in this lesson:
After discussing how to implement D3 brush, Shirley live codes an example showing how to add brush interactivity to a chart.
Transcript from the "Brush Exercise & Solution" Lesson
[00:00:00]
>> Shirley Wu: What you are doing data visualization and react, I think that's one of the best things of using them together. That you get these kind of really fancy interactions that look really complex, for nearly free. This is really easy to implement and I'm going to show you how.
[00:00:19]
So, like with the axes, what we want to do is create a brush instance in componentDidMount. We want to define the brushable area with this extent. So in this case the extent is defining this, so this is the top left corner and this is the bottom right corner and all this means that it's saying like, a user can brush between those points within that area but not more past it.
[00:00:54]
And so that's pretty important or else you can imagine if we don't define that, then somebody might just try and do a brush from this corner to this corner or something. And you want to be able to limit to just say to this bar chart. So that's what this .extent is for, quite important.
[00:01:15]
Also very important pass in a function to execute on every brush interactions. So if like the person is dragging the brush or after they they've drag the brush and they've let go pass in a function to execute. When that happens and that's important because, well you'll see in a little bit what D3 brush gives you and then we'll talk about why that's really important.
[00:01:47]
Like before, in render,
>> Shirley Wu: Create the group component. And then in componentDidMount instead of componentDidUpdate in componentDidMount because you only need to do this once. You need to, you only in D3 only need to create these DOM elements once. So, in componentDidMount, select that group and call the brush generator function and this is all it takes.
[00:02:18]
This first part, this render, and this third part, and then some function to execute after the brush is released. And that's all you need for The functionality you saw before. So let's add that interaction into the bar chart so that we can see exactly how easy it is.
[00:02:45]
So,
>> Shirley Wu: What we want to do is, actually let me, so this is a. Live, you can play with this, so this is kind of the functionlity. So let's do that first. Okay so we have the bar chart that we ended up with before, and then let's add the brush capability.
[00:03:20]
So, what I mentioned before is that we need to do this end component amount. So first, let's create the brush and component amount. This .brush is equal to d3.brush and then we're going to give it the brushable area with extent and we passed that in. It's an array of arrays.
[00:03:46]
And so we give it,
>> Shirley Wu: The top left corner. And in that case, for us, the top left is the exposition is margin.left and then the y position is margin.top, and then this is our bottom right corner of the brushable area. And that is width minus margin.right and height minus margin.top.
[00:04:43]
>> Shirley Wu: So we've defined that. And then we're just gonna do a function for when the event ends, when the brushing ends, do something here. So, I'll leave that blank for now. And then, and here in the render, I'm going to create a group with a rough brush like I did for the axis
[00:05:22]
>> Shirley Wu: And then I'm going to select that using d3.this.refs.brush
>> Shirley Wu: And then I'm going to call this.brush. And so those are the three things I mentioned and now you can see I have this little rectangle that I can drag around and use as a brush. Now you might have noticed that even though I'm dragging it around nothing is happening within this chart.
[00:06:03]
Nothing is getting grayed out, nothing over here is getting grayed out.
>> Shirley Wu: And the reason for that is because all D3 brush does for us is it gives us this little interactivity. And then, while you're brushing or on brush end and it gives you D3.event.selection. And what that does is give us then i am going to make this brush X, oops, sorry.
[00:06:49]
I am just going to make it a horizontal brush, so brush X is a horizontal brush and brush Y is a vertical brush, and then if it is just brush, it is a brush in both directions. So for us today, I'm just going to use a horizontal brush like this.
[00:07:04]
And then you can see these tiny little, so, what D3 gives us with D3 brush is this functionality as well as these numbers. Which is basically your
>> Shirley Wu: This is your x0 and this your x1. So basically it gives us back the x position of the left hand side and the x position of your right hand side.
[00:07:42]
And this is really important because then what I can do is say, I want the 2x positions so i can say- min x and max x is equal to d3.event .selection. And then this is another place where d3-scale is really cool because I can then, oops.
>> Shirley Wu: Say give me back.
[00:08:32]
>> Shirley Wu: For the min x, give me back the corresponding dates. So the x scale that we learned about at the very beginning of the class. That one was taking a date and turning it into a x value, right? But scales are really cool in D3, because if you just do it .invert, what you can do is give it an x value, give it a range, and it will give you back the domain.
[00:09:01]
So if I just do this right now, what I'm going to get is the date of this x position
>> Shirley Wu: So if I do that it's gonna give me, so it's telling me it's April 10th. So this is April 10th, and then you can imagine if I do
[00:09:28]
>> Shirley Wu: xScale.invert then max. Then as soon as I do this, it will tell me, this exposition is February 6th, and this exposition is June 3rd. And now from here on, everything is react, because basically what we want to do is propagate. So we just want to set this on the parent component.
[00:09:56]
We want this to be a state on the parent component. So let me open up app.js and I have this thing called range that I'm going to give a time range. And then I already have this function that I wrote called update range. All that is is takes that array and sets state.
[00:10:24]
I'm going to pass both of those into my charts. So I'm going to pass in, on top of the data, I'm going to pass in that range. And I'm going to pass in that function. And I've done that for the bar chart above right here. I've done that for the radio chart and right now I'm gonna do it for the chart that we're modifying.
[00:10:51]
So I say, this.state.range and updateRange is equal to this.updateRange the function. And now I can go back into my Chart.js and at the very end of this function, I can say that this. Alt props, dot, update range, and passing that range. And then, once I do this, everything here updates accordingly.
[00:11:29]
But notice were one more step away from being done. Because right now everything here is still colored. And that is as simple as saying, when we're calculating the bars, let's calculate if it should be colored or not. If this particular bar should be colored or not, and the way that we want to do that is let's say,
[00:11:57]
>> Shirley Wu: Let's get the range out of the props.
>> Shirley Wu: And we'll say if there's no range, or if this,
>> Shirley Wu: or if this bar, the date of this bar is greater than the minimum dates and less than the maximum dates. Than it should be colored and so in here in the fill we'll just say is, colored.
[00:12:35]
and it should be colored then, and let's use the color scale, and if not let's pass in some grey. And, yes.
>> Shirley Wu: That is not what I was expecting. It is colored.
>> Speaker 2: Arranged out lane?
>> Shirley Wu: Thank you so much. Yes, cuz it's an array. Thank you. Yes, so if there's range.length, thank you.
[00:13:06]
And now, if I do the brush, everything is hooked up. And these will be colored within and gray without. And because I have this same exact code on the radio chart and the other bar chart
>> Shirley Wu: The brushing will work. Look at that. That's so that's really interesting because I have this brushing and this brushing and so whatever is the latest brush will overwrite the other one.
[00:13:41]
Not, I think that's more a bug than a feature, but. But the point is the point is Look. That's how easy it was. Those three steps to draw the brushable area. And then using D3.event.selection, getting the min x and the max x, inverting that back to the dates, setting that on the root component.
[00:14:09]
And then from there on, it's everything you probably already usually do with your React.Components to get this interaction, like this very fancy looking interaction that actually doesn't need that much code.
>> Speaker 3: Can you talk a little bit more about that invert part?
>> Shirley Wu: Yeah. So there's actually not much more to say other than to say so scales are to go from your domain to the range.
[00:14:40]
But sometimes you just want to go from the range to the domain, and when that happens, you want to use dot invert. And so this is really, really, great when you have user interaction and especially if that user interaction gives you back an x-y position on the screen or something like that.
[00:15:01]
And you want to ma that back to your raw data so that you can do something like filtering or aggregating. So you can imagine, you can do the same exact thing if this was like a 2 dimensional brush, and then you can get the y, the min y, the max y, etc.
[00:15:19]
And then get the temperature back, that's also another thing. And let me filter by the temperature, and only color the bars where it's within that temperature range. So you can do something like that also. And that's what invar is really really good for. And I think you can do this for almost every single scale I think you can do this for almost every single scale.
[00:15:47]
Instead of going from your raw data to the screen space, it's for when you want go from your screen space back to your raw data. Yeah. Thank you for that question.
>> Speaker 4: You'd use brush for.
>> Speaker 4: Do you use brush for anything besides just coloring the data? I'm assuming you can change of data set, zoom in, or?
[00:16:06]
>> Shirley Wu: So I can show you something that's not my example.
>> Shirley Wu: But it's called Crossfilter. I think this is not maintained anymore. But you can imagine, for example this is, I think, airline time performance. So this whole thing is a dataset and then this is talking about ,it's like just a bunch of histograms and times of days.
[00:16:33]
So you can brush and filter let's say like you just want to see airplanes that I guess go between 6 AM to 2. You want to see the ones that are, have it, arrival delay of, I mean, that’s a bad, [LAUGH] Line. [LAUGH] I mean, do you want to see all the ones that have, are going long distances, maybe these are cross continental, wait, hold on.
[00:17:04]
Cross ocean and lets say you want it to see it in maybe you only want to see it in spring time and then that nose down your data set. And this is really, really cool cuz it's really cool for exploratory, visualizations where like where I guess more to.
[00:17:40]
Be able to filter down by a bunch of different dimensions of the data and then come to like a final results. And this is I think the most common way I see brush is being used but obviously there is like other examples. This one's a fun one. I think this is like the RGB.
[00:18:06]
And then if you move it around her. [LAUGH] It just shows you the color makeup of that section I believe.
>> Shirley Wu: So anywhere from useful to fun. [LAUGH]
>> Speaker 4: Arc you were talking about earlier?
>> Shirley Wu: Sorry, what?
>> Speaker 4: What's the data arc you were talking about earlier?
>> Shirley Wu: Yeah, I, yeah.
[00:18:37]
[LAUGH]
>> Shirley Wu: So I mean, it's basically the funnest part of all of this is thinking about applications for each of these functionalities that might be outside of the box, right? Like these might be the things that people usually do with it, but then if you can think of where else this can be applied that's the fun part, right?
[00:19:03]
So, yeah, this is brushes. And I wanted to show it because it's really fun. And it's quite easy. So, I think those cross-filter examples are maybe six or seven years old. And I think it's If I remember correctly it's relatively complicated to do this but then in React it's super easy to do.
[00:19:27]
Because React is all about interactions with one section of your page that will update other parts of your page really easily.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops