In a previous assignment you wrote a program that analyzed the sentiment of real-world Twitter data. This program ran on the command-line; while that allowed you to quickly adjust the dataset you analyzed and possibly redirect the output elsewhere, the text-based output wasn't the most friendly to read or interact with (which is important if you want to share your data and analysis with others).
So for this assignment, you will implement a version of your Twitter Sentiment program that runs in a web browser, enabling people to search for a Twitter user and view an analysis of the sentiment of their timeline without needing to use the command-line.
(Note that the page styling is all provided for you).
By completing this assignment you will practice and master the following skills:
- Porting code from one language to another
- Dynamically generating webpage content
- Responding to user input using asynchronous programming
Follow the below link to create your private code repo for this assignment. You will need to accept this assignment to create your code repo. Do not fork this repository!
fork this repository!
After you've accepted the assignment,
clone the repo to your local machine so you can edit the files. Make sure you don't clone it inside another repo!
This repo contains a basic web page (the
index.html file) that executes the
tweeter_sentiment.js script, which you will need to implement. You will need to define required functions, and then call them to perform your data analysis.
The repo also contains a
data/ folder containing data files you'll be using. This data has already been imported into your script as global variables
SENTIMENTS (the object of word sentiments),
EMOTIONS (the array of emotions), and
SAMPLE_TWEETS (the array of "tweet" objects). Note that the format of the data structures is identical to those in the previous assignment; see that specification for details.
In order to have your web page access remote data (like from Twitter), it needs to be running from a local web server (this is a security measure). You can easily create a web server using Python. On the command-line, while inside the repo folder, run:
python -m http.server
-m option lets you run a built-in module as script, instead of just importing it). You can then access your web page through your browser at: http://localhost:8000/
console.log() to log out
"hello world" from the
tweeter_sentiment.js script and reload the web page. If you can see your message, then you're ready to go!
A function to split up the tweet's text (a string) into individual words (an array).
/ / instead of the
" " used for strings.
filter() functions on an array to perform mapping and filtering.
A function that filters an array of words to only get those words that contain a specific emotion.
get() method like Python dictionaries. If you try to access a key that doesn't exist, you'll get the value
undefined. You can use this to check (e.g., with an if statement) whether or not a particular key is in an object.
A function that determines which words from an array have each emotion, returning an object that contains that information.
- This should return an object structured exactly like the Python dictionary described in the previous assignment.
A function that gets an array of the "most common" words in an array, ordered by their frequency.
sort() function that takes in a callback function as an argument (similar to the
key argument in Python's method).
analyzeTweets() function that takes in an array of tweets and returns an object containing the data of interest.
- Once again, this function will mirror your Python function. Use the array's
reduce() method to perform reducing operations.
You should be able to test all of these functions individually using the examples from the previous assignment. You can test that they all work by passing the included
SAMPLE_TWEETS variable into the
analyzeTweets() function, and then using
console.log() to output the returned result (explore the object through Chrome's developer tools).
Once you've analyzed the tweets, you'll need to display that information as a table on the web page. The table headers are included for you—you just need to fill in the data!
Implement a separate function (e.g.,
showEmotionData()) that will display this table. The function should take as an argument the data structure returned from your
analyzeTweets() function. It will be called from the bottom of your script, and passed the result of that function.
In order to output this table, you will need to add a new row to the table for each emotion. Rows will be represented by a
<tr> (table row) HTML element, which includes inside it multiple
<td> (table data, or table cell) elements. For example:
<td>faculty, learn, information</td>
<td>#accesstoinfoday, #indigenouspeoplesday, #idealistfair</td>
Adding a row to a table is pretty simple. There are a few steps:
First, you need to get a reference (a variable) to the body of the table (a
<tbody> element with an id of
#emotionsTable). You can do this by using the
d3.select() function (the
d3 library is automatically imported by the provided code). Note that since this table won't change for each emotion, you might only do this once before you go through each emotion.
You will then need to create a new row. You can do this using the
d3.append() function, specifying the element type (
tr) you wish to append (without the `<>). This function will return a reference to the row.
You can then define a string variable that will contain the HTML of the row's content (that is, the four
<td> elements). Use string concatenation to include variable (or a template literal).
You can include this HTML string in the webpage by calling the
html() method on the DOM element you wish to put it in (e.g., your
<tr> row), passing in the HTML string as an argument.
- All formatting rules from the previous assignment should apply: give the percentage 2 decimals of precision (use the
toFixed() method., include commas and spaces between the words/hashtags in the list, and include a
# in front of the hashtags.
Note that you should also remove any previous contents that might be in the table (e.g., by setting the table's HTML to be an empty string
It is also possible to do this using built-in DOM methods and not D3. You can select the table body to get a variable reference to it. Then you create a table row and append it to the table. For each row, you can then create and append a series of table data elements, setting the content of each to the appropriate value.
Finally, we can add in the ability to search for user names and display live data!
Implement another function (e.g.,
loadTweets()) that takes in a Twitter username. This function should send an AJAX request (an asynchronous HTTP request) for the user's timeline data, analyze that data (using your
analyzeTweets() function), and then display the results (using your
You can send an HTTP request (for some JSON data) using the D3 provided
d3.json() function. This function takes in two arguments: the URI to send the request to, and a callback function that will be executed asynchronously after the data has been downloaded.
This method doesn't support any kind of argument for specifying the query parameters; you will need to construct the complete request URI yourself. You should continue to utilize the proxy url
The callback function, when executed, will be passed a single argument: the JSON object returned by the query. You should be able to pass this object directly into your
You can test this functionality by calling your method and passing it a Twitter username (e.g.,
uw_ischool)—you should see some analysis appear in your table!
The last step is to allow the user to specify the username they want to analyze in the web page's "search box", and have the analysis occur and display when the user clicks the "search" button.
There are a couple of steps to do this:
You will need to get a reference to the search button (it has an id of
#searchButton) using the
d3.select() function, just as you did for your table. You should do this at the "global" level (e.g., after defining the functions, where you have been calling them), rather than in a specific function.
You'll need to attach a click listener to the button by calling the
.on('click', callback) function. The second argument is a callback function that will be executed only after the user clicks the button (e.g., asynchronously!)
In that callback function, you will need to get a reference to the search box (id of
#searchBox), and then access the value that the user has typed in. You can do this by calling the
property() method on the search box, passing it an argument of
'value' (which is the property you want to access).
Finally, you can take that value and pass it as an argument to your
loadTweets() function, thereby causing the search to be executed and displayed!
That's it! You should now be able to search for Twitter users and analyze the emotions of their timeline.
Please still have your script show the analysis table for the
SAMPLE_TWEETS variable when the web page is first opened (it should not load a blank table)! This will help us out with grading. You can do this by simply retaining your testing calls to analyze and show the sample tweets. The live data will be downloaded and displayed when someone clicks "search".
Since you've created this neat analysis program, you should also put it online! Publish your repository to GitHub Pages by creating a new
gh-pages branch and pushing that to GitHub. You should then be able to visit
in order to user your program. Note that sometimes it takes a few minutes for GitHub Pages to update with new files, so be patient if they don't show up initially (you can check that the code is pushed correctly by checking the
gh-pages branch on the GitHub web portal).
Be sure that any future changes are made on the
master branch, not on
gh-pages (we'll be grading the code on
master). If you made additional changes, you will need to then
merge them into the
gh-pages branch (watching out for any merge conflicts). If you hit any problems, ask for help!
In order to submit this assignment
Confirm that you've successfully completed the assignment. We should be able to search for a user's timeline and see the correct results. Double-check that we can perform multiple searches (e.g., for different users)!
commit the final version of your work, and
push your code to your GitHub repository (to the
Publish your visualizations to the
gh-pages branch on Github, as described above. Make sure you publish the final version!
Make sure that you've filled out the Submission form for this assignment, answering all the questions.
Submit the URL of your GitHub Repository AS WELL AS the link to your published application (2 links total) as your assignment submission on Canvas (this page, at the top).