The goal of this project is to create a set of interactive and dynamic data visualizations using exoplanet data from the NASA Exoplanet Archive. My web app includes five barcharts, a timeline of exoplanet discoveries, a scatterplot displaying the relationship between exoplanet mass and radius, a histogram categorizing exoplanets by their distance in parsecs, and a data table allowing users to interact with the data. Additionally, users can select an exoplanet from the table to open a host system simulator and view data about the host star(s) and other exoplanets in the system.
The project was developed using primarily JavaScript, HTML, and CSS and can be run locally by cloning the main branch of the GitHub repository and opening the index.html file in a web browser. The exoplanet data used in the project was obtained from the NASA Exoplanet Archive, and the visualizations were created using D3.js.
Each of the bar charts and the histogram are interactive and can filter the data based on the column clicked. These visualizations feature real-time data updates, animations, responsive styling, and tooltips. Additionally, the discover method and star type bar charts have help buttons to learn more about exoplanet discovery and stellar classification.
The line chart plots exoplanets by their discovery year. This line chart features a tooltip after hovering over the line chart using the D3 bisector to find the closest point to the mouse. The tooltip displays the number of exoplanets discovered in a specific year. If the user clicks, it will sort the data and only show exoplanets discovered that year.
The scatterplot plots exoplanets by their mass and radius (in Earth units) along logarithmic scales. This scatterplot features tooltips and brushing, allowing users to hover over individual data points to learn more about specific exoplanets and select specific points from the graph. The scatterplot also includes the planets in our Solar System and a filterable legend of star types. Clicking on an individual exoplanet will open the system viewer.
The table displays exoplanet data, including discovery facility, planet radius, and planet mass. If the user selects an exoplanet from the table, the host system simulator will appear below. Additionally, if the user applies any other filter from the above visualizations, the table will update to only show the filtered data.
Selecting an individual exoplanet in either the table or scatterplot will open the Host System Viewer and display a scale model of all other exoplanets orbiting the same star. The viewer features tooltips, allowing users to learn more about the host star and other exoplanets in the same system.
To use this web application, visit the latest deployment or clone the GitHub repo and open the index.html file in a web browser. The data should be automatically loaded and the data visualizations should appear on the screen.
To filter the data, click on any of the bars in the barchart or on a year in the line chart. The scatterplot also features a brush to create a selection of points. After applying a filter or selection, all the visualizations should update to only include the data based on the filter applied. For example, clicking on the "A" bar in the Star Type barchart will update the visualizations to only include exoplanets orbiting an A-type star.
After applying a filter or selection, the "Reset Data" button will enable in the top left of the screen. Clicking the button will reset the data to include all exoplanets and refresh all visualizations. The reset button will then be disabled until another filter or selection is applied.
To open the System Viewer, select an individual exoplanet from either the table or scatterplot. The System Viewer will open and automatically display other planets orbitting the same star. To close the viewer window, click the button in the top left corner of the viewer.
This d3.js web app utilizes data obtained from the NASA Exoplanet Archive, operated by the California Institute of Technology. This data includes the planet's name (pl_name), the system name (sys_name), the number of planets in the system (sy_pnum), as well as discovery information, including the method used to discover the planet (discoverymethod), the year of discovery (disc_year), and the discovery facility that first observed the exoplanet (disc_facility).
Additionally, this web app incorporates details about the planet's orbital maximum distance (pl_orbsmax), radius (pl_rade), mass in Earth masses (pl_bmasse), and eccentricity (pl_orbeccen). The host star's spectral type (st_spectype), radius (st_rad), mass (st_mass), and the distance from Earth to the system (sy_dist) are also included in the data.
To begin the development process, I first loaded the CSV exoplanet data into the program using d3.csv. I then created a barchart.js file capable of creating a barchart using a data array passed to the constructor. The barchart.js file contains all of the necessary functions for creating a bar chart, such as initVis, updateVis, and renderVis.
In my main.js, I initialized five barcharts using the BarChart class and calculated the necessary counts for the data in separate functions. I then passed each data array of counts to its respective barchart. I also created histogram.js and the Histogram class, very similar to the BarChart class but processes the count array differently. Additionally, I created a line.js file that creates a line chart using discovery year data featuring tooltips using D3's bisector. I initialized it in my main.js and calculated the discovery year count before passing it to the line chart. I did the same thing with my scatterplot.js, adding the planet radius and mass of all known exoplanets into an array and passing it to the scatterplot. The scatterplot even skips exoplanets with an unknown radius and/or mass. Finally, I created a table based on the exoplanet data after loading all of the d3 elements.
Each d3 element I listed above (barchart, histogram, line chart, scatterplot) has a callback function used to filter the data. In each class, I have a mouse click event listener that listens for when a user clicks on a bar in the barchart, in the trackableArea in the timeline, or if they used the brush on the scatterplot. When this event listener is triggered, it calls the callback function which updates the data using the event parameter and updates the rest of the visualizations.
To reset the data, I implemented a reset filter button at the top left of the page that reloads the default data for every visualization element. I also implemented a loading message that pops up by conditionally rendering a paragraph element at the start and end of my resetFilter and filterData functions.
Lastly, this web app also features a host system viewer showing a scale model of an exoplanet's solar system. The system viewer is created using the System class constructed in system.js, and uses data passed by the setExoplanet function called by the table and scatterplot. If a user selects an individual exoplanet in either of these visualizations, setExoplanet will filter all other exoplanets orbiting the same star and pass it to the system viewer. When the setExoplanet function is called, the system viewer window opens by switching the "display" style from "none" to "flex" and blurs the rest of the screen until the system viewer is closed.
I also ensure missing data is handled appropriately throughout the application. Most of the time, I simply had to check if a certain column is undefined or not and conditionally render certain text. For example, in the above code snippet from my system viewer, I check if st_rad is defined. If not, I assume stellar data is not available and render it on the screen. I also used multiple ternary operators throughout the web app, for example:
I also added logic to handle planets with blank pl_orbsmax or pl_rade values in the System Viewer. If pl_orbsmax or pl_rade was blank, I moved the planet to the bottom left of the System Viewer window with a tooltip explaining the orbital axis and/or planet radius is unknown. Similarly, I notify the user if stellar data is unavailable.
Radius missing
Orbital axis missing
Stellar data missing
Stellar data and radius missing
Orbital axis missing
I also added a planet color scale using D3's ordinal scale.
After finishing all of the data visualizations, I used simple HTML and CSS styling to add a container to each of the visualizations. I rounded the corners, added a box shadow and background color, and applied it to each visualization.
Test cards created during development
Overall, developing this project was a valuable learning experience for me. By using D3.js and the provided exoplanet data, I was able to create effective and engaging visualizations while also learning about designing readable and responsive layouts capable of handling large datasets. This project expanded my skills in data visualization and layout design, and I look forward to applying these skills in the remaining two projects as well as areas outside this course.
If you found this project interesting, be sure to check out the Exoplanet Archive Search created for my senior design project.