In this assignment, you will write code to build an interactive visualization for the well known Iris Dataset. Your main focus will be on designing linked views that enable interaction through selection and brushing. To do so, you will create two scatterplots to visualize the four quantitative dimensions of the data.

Please click here to create your repository

Objectives

This assignment is designed to get comfortable with brushes and linked views in d3. Specific objectives include:

  • Practicing the design of multiple views visualizations
  • Learning how to define interactions in d3, particularly through implementing click events for selection and d3.brush’s for brushing and linking.
  • Experimenting with d3 brush callbacks for both types of events
  • Practicing the use of d3 filters for capturing selected data objects
  • Understanding how to compose all of the above skills to create an interactive visualization that allows for overview and details-on-demand

Description

In this assignment, you will create a visualization with linked views and interactive brushing.

You will use the Iris dataset, a classic dataset that is used for prototyping in visualization and machine learning. This dataset has four quantitative attributes (sepal length, sepal width, petal length, petal width) and 1 categorical attibute (species). There are 50 samples in each of 3 species (setosa, versicolor, and virginica), for a dataset with 150 total flowers.

Your visualization will consist of two side-by-side scatterplots. The first scatterplot will have the sepal length and sepal width as \(x\)- and \(y\)-axes, and the second scatterplot will show petal length and petal width. You should use color to encode the species of each flower.

In addition, the visualization will support interaction via linked views: point(s) selected in one view will be highlighted in the other view. Finally, as users click on a point in either scatterplot, you will show the actual values of that particular student in a separate, third tabular view.

Part 1: Scatterplots

You should finish the implementation of the function makeScatterplot(). This function should be generic, as it will be reused for both of the scatterplots. To make it general, you will pass in specific functions to access the \(x\)- and \(y\)-values (called xAccessor and yAccessor). The assignment template illustrates how to use these.

Each scatterplot should have scales and axes defined for the coordinates. These axes should be labeled. Each data point should be drawn as a dot whose position should be encoded using these scales. You should set the radius of this dot to a constant. The color of the data should be defined by the category of the iris type, and the same colors should be used in both scatterplots to help visually cluster the data.

Feel free to use code from previous assignments to create this, in particular setting up approach padding and using the data join pattern.

Part 2: Selection and Highlighting

When the user clicks on a dot in either scatterplot, the actual data record associated with that particular data element should be displayed in the html table. To do so, you will have to implement a callback function that responds to .on("click",...) and attach this callback to each circle during the main data join.

To help design the callback function, check out d3’s Handling Events documentation. Essentially, the callback function will be a function that accepts two parameters, event and d, which are the d3 event object and the current datum. (Note: older version of d3 had a slightly different signature, so when you’re looking for examples online keep this in mind. See https://observablehq.com/@d3/d3v6-migration-guide#events for more details.)

To display the data record, your callback should then use d3 to adjust the .text() field for the appropriate DOM elements.

In addition, when a user clicks on a point in either scatterplot, the corresponding point on the other scatterplot is highlighted, by making both dots be shown with an enlarged radius. This will likely require you to implement a mechanism for indexing the same data element as it exists within both plots.

Finally, when one clicks on a different dot, the previous dots must be restored to their original size.

Part 3: Brushing and Linking

When the user drags the mouse on either scatterplot, a rectangular brush is drawn on that scatterplot, indicating the region of interest. All the points with attributes inside the brushed region are considered selected. Selected points should be drawn in a unique stroke color while unselected points should be drawn with no stroke. I recommend using a stroke color that is more saturated to help the selection visually popout.

Moreover, if the user creates two separate brushes, selected points must satisfy the logical “and” of the criteria of the two brushes. This means you should only highlight dots which are within both selections. If no brush is active, the points should be drawn in their original style that indicates their species.

To accomplish this, you will implement the onBrush() function. I have provided code that configures the brush in makeScatterplot() and sets up the approach callbacks for the .on("brush",...) and .on("end",...) events. In each case, these callbacks store the event.selection object for the brush in the global variables brush1 and brush2. These objects store the extents for each brush in pixel coordinates. See the template code for how precisely how they are stored.

Using the selection objects, onBrush() should create a filter function, isSelected(), that will return true if a data element is contained within the active selection regions of both brushes. onBrush() is then implemented so that it uses all circles (from both plots) and applies this filter to identify the data elements that are selected. Selected elements should be stroked using the highlight stroke color, while not selected elements should be reverted to the visual appearance based on their species.

You may want to skim Documentation for d3’s brushes before starting this assignment. Note that although d3’s brushes are available as a separate library, you do not need to include d3-brush explicitly yourself, run npm install, etc. The brush library is packaged with the version of d3 included in the template repository.

Submission

You should use git to submit all source code files. The expectation is that your code will be graded by cloning your repo and then executing it within a modern browser (Chrome, Firefox, etc.)

Please provide a README.md file that provides a text description of how to run your program and any parameters that you used. Also document any idiosyncrasies, behaviors, or bugs of note that you want us to be aware of.

To summarize, my expectation is that your repo will contain:

  1. A README.md file
  2. A index.html file
  3. An a07.js file
  4. All other Javascript files necessary to run the code (including iris.js and d3.js plus any others you require)
  5. Any .css files containing style information

Grading

Deductions

Reason Value
Bugs or syntax errors -10 each bug at grader's discretion to fix


Point Breakdown of Features

Requirement Value
Consistent modular coding style 5
External documentation (README.md) following the template provided in the base repository 5
Header documentation, Internal documentation (Block for functions and Inline descriptive comments). Wherever applicable / for all files 10
Expected output / behavior for your chart based on the assignment specification, including

Implementing the two scatterplots, with appropriate visual encoding for positions and fill colors, axes, and labels20
Implementing selection for details-on-demand displayed within the html table15
Implementing highlighting between plots by enlarging the radius of the selected data element in both plots15
Correctly implementing the onBrush function so that the points returned by isSelected are highlighted, and all other points are colored by their species15
Correctly implementing the logic for the isSelected function so that it returns true for selected points and takes the logical and of both brushes15

100
Total 100/100


Cumulative Relationship to Final Grade

Worth 6% of your final grade

Extra Credit

Implementing features above and beyond the specification may result in additional extra credit, please document these in your README.md.