Towards Interactive Visualizations
Interactive Visualizations
Interactivity may take several forms:
Interactive Visualizations
To interact with elements, we need to understand how to refer to existing elements.
Interactive Visualizations
svg.selectAll("circle")� .data(college.courses)� .enter()� .append("circle")� .attr("class","courses")� .attr("cy", function (d) { return courseMajorScale(d.subject); } )� .attr("cx", function (d) { return courseNumberScale(d.number); } )� .attr("r", function(d) {� if (d.number < 100 || d.number >= 500) { return 0; }� else { return Math.pow(width * 1.5 * (d.sum_students / r_max), 0.5); }� })� .attr("fill", function(d,i) { return gpaScale(d.avg_gpa); })� .on('mouseover', function(d,i) { /* ... */ })� .on('mouseout', function(d,i) { /* ... */ })� ;
Attributes that easily select nodes
To modify a visualization, we need to select existing nodes already rendered. HTML and d3.js provides two easy ways to do this:
svg.selectAll("circle")� .data(college.courses)� .enter()� .append("circle")� .attr("class","courses")� .attr("cy", function (d) { return courseMajorScale(d.subject); } )� .attr("cx", function (d) { return courseNumberScale(d.number); } )� .attr("r", function(d) {� if (d.number < 100 || d.number >= 500) { return 0; }� else { return Math.pow(width * 1.5 * (d.sum_students / r_max), 0.5); }� })� .attr("fill", function(d,i) { return gpaScale(d.avg_gpa); })� .on('mouseover', function(d,i) { /* ... */ })� .on('mouseout', function(d,i) { /* ... */ })� ;
Selecting Existing Nodes
Selecting existing nodes uses the same syntax we’ve seen before, with one additional piece:
Example: A Simple Grade Visualization
demo_interactive_d3 contains a simple visualization of student grades on an exam:
svg.selectAll("grade")� .data(data)� .enter()� .append("circle")� .attr("class", "grade")� .attr("r", function (d, i) { return 4; })� .attr("cx", function (d, i) { return gradeScale( d["grade"] ); })� .attr("cy", 0)� .attr("fill", "red")� .attr("stroke", "black")� ;
Example: A Simple Grade Visualization
Goal: When an element is moused over, fade all of the other elements:
1. Add a mouseover event
svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {����� })� ;
2. Select all of the grade elements
svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {� svg.selectAll(".grade")���� })� ;
3. Fade the elements
svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {� svg.selectAll(".grade")� .style("opacity", 0.1);��� })� ;
Example: A Simple Grade Visualization
Goal: When an element is moused over, fade all of the other elements:
It works, kinda:
Example: A Simple Grade Visualization
Goal: When an element is moused over, fade all of the other elements:
Filtering a Selection
With a selection, .filter can be used to remove some elements from your selection:
.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {�� })� .style("opacity", 0.1);� })
Filtering a Selection
When inside of an event handler, there are two changing variables:
.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {�� })� .style("opacity", 0.1);� })
Filtering a Selection
The filter function must return true for elements that should remain as part of the set:
.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {� if (d == e) { return false; } /* remove self */� else { return true; } /* keep others */� })� .style("opacity", 0.1);� })
Filtering a Selection
The filter function must return true for elements that should remain as part of the set: � .on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {� if (d == e) { return false; } /* remove self */� else { return true; } /* keep others */� })� .style("opacity", 0.1);� })
Example: A Simple Grade Visualization
Goal: When an element is moused over, fade all of the other elements:
...and reverse this process when the mouse is moved away (mouseout).
Revising the Fade
.on("mouseout", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {� if (d == e) { return false; } /* remove self */� else { return true; } /* keep others */� })� .style("opacity", 1);� })
Adding Visual Smoothing to Transitions
When styling visual elements, transition properties can be applied to provide a visual smoothing to transition effects:
.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {� if (d == e) { return false; } /* remove self */� else { return true; } /* keep others */� })� .transition()� .duration(1000) // milliseconds (ms), 1000ms == 1sec� .style("opacity", 0.1);� })
.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {� if (d == e) { return false; } /* remove self */� else { return true; } /* keep others */� })� .transition()� .duration(1000)� .style("opacity", 0.1)� .transition()� .duration(1000)� .style("opacity", 1.0)� .transition()� .duration(1000)� .style("fill", "blue");� })
We can chain them too!