1 of 25

Towards Interactive Visualizations

2 of 25

Interactive Visualizations

Interactivity may take several forms:

  • Mouseover / Mouseout: Do something when a user moves her/his mouse over an element in the visualization.
  • Click: Do something when a user taps or clicks an element in the visualization.
  • Selection Change: Do something when a checkbox or dropdown is changed.�
  • Any standard event supported by the browser:� https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events

3 of 25

Interactive Visualizations

To interact with elements, we need to understand how to refer to existing elements.

  • When we run d3.js code, we are adding content to the HTML that is rendered by the web browser.�
  • We can inspect a d3.js visualization to see the HTML tags that d3.js added.

4 of 25

Interactive Visualizations

5 of 25

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) { /* ... */ })� ;

6 of 25

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:

  • If we want to select a group of elements (ex: all the courses), assign every element a class attribute with the same name.
    • We can later refer to every element that has a specific class name.�
  • If we want to select a single element (ex: a single button), assign the element an id attribute with a unique name.
    • We can later refer to that unique element by the id name.

7 of 25

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) { /* ... */ })� ;

8 of 25

Selecting Existing Nodes

Selecting existing nodes uses the same syntax we’ve seen before, with one additional piece:

  • If we are selecting nodes by their class attribute, add a period before the class name (ex: ".courses") �
  • If we are selecting nodes by their id attribute, add a hashtag before the class name (ex: "#courses")

9 of 25

Example: A Simple Grade Visualization

demo_interactive_d3 contains a simple visualization of student grades on an exam:

10 of 25

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")� ;

11 of 25

Example: A Simple Grade Visualization

Goal: When an element is moused over, fade all of the other elements:

  1. Add a mouseover event
  2. Select all of grade elements
  3. Fade the elements

12 of 25

1. Add a mouseover event

svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {����� })� ;

13 of 25

2. Select all of the grade elements

svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {� svg.selectAll(".grade")���� })� ;

14 of 25

3. Fade the elements

svg.selectAll("grade")� /* ... */� .on("mouseover", function (d, i) {� svg.selectAll(".grade")� .style("opacity", 0.1);��� })� ;

15 of 25

Example: A Simple Grade Visualization

Goal: When an element is moused over, fade all of the other elements:

  • Add a mouseover event
  • Select all of grade elements
  • Fade the elements\

It works, kinda:

16 of 25

Example: A Simple Grade Visualization

Goal: When an element is moused over, fade all of the other elements:

  • Add a mouseover event
  • Select all of grade elements
    1. ...and filter the selection to include the other nodes...
  • Fade the elements

17 of 25

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);� })

18 of 25

Filtering a Selection

When inside of an event handler, there are two changing variables:

  • d (from the event handler): Contains data corresponding to the element fired the event (ex: the element being moused over).�
  • e (from the filter): Contains data corresponding to the element that is currently being considered by the filter

.on("mouseover", function (d, i) {� svg.selectAll(".grade")� .filter(function(e) {�� })� .style("opacity", 0.1);� })

19 of 25

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);� })

20 of 25

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);� })

21 of 25

Example: A Simple Grade Visualization

Goal: When an element is moused over, fade all of the other elements:

  • Add a mouseover event
  • Select all of grade elements
    • ...and filter the selection to include the other nodes...
  • Fade the elements

...and reverse this process when the mouse is moved away (mouseout).

22 of 25

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);� })

23 of 25

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);� })

24 of 25

.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!

25 of 25

Tooltips