From 60f068226f2d906d59ceba0368d592a6b4659398 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 11:21:25 -0400
Subject: [PATCH 01/11] likedMusicHistory initialize
---
.../main/java/com/google/musicanalysis/site/YoutubeGenres.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
index 76374236..0e3abcfb 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
@@ -22,6 +22,7 @@ public class YoutubeGenres {
public HashMap genreData = new HashMap();
public int totalMusic = 0;
public int maxGenreCount = 0;
+ public int[] likedMusicHistory;
public YoutubeGenres() {
From cc80ea332b94adaa5f8407fbbca8a5dc6332bde0 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 11:46:51 -0400
Subject: [PATCH 02/11] implemented likedMusicHistory
---
.../google/musicanalysis/site/YoutubeGenres.java | 16 +++++++++++-----
.../musicanalysis/site/YoutubeServlet.java | 4 +++-
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
index 0e3abcfb..8fe7dee4 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
@@ -4,6 +4,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import com.google.gson.Gson;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.lang.Math;
@@ -22,7 +23,7 @@ public class YoutubeGenres {
public HashMap genreData = new HashMap();
public int totalMusic = 0;
public int maxGenreCount = 0;
- public int[] likedMusicHistory;
+ public ArrayList likedMusicHistory = new ArrayList();
public YoutubeGenres() {
@@ -33,7 +34,7 @@ public YoutubeGenres() {
* updates hash map to contain frequency count of each music genre
* @param videos json array of youtube liked videos
*/
- protected void calculateMusicCount(JsonArray videos) {
+ protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
for (int i = 0; i < videos.size(); i++) {
JsonObject video = videos.get(i).getAsJsonObject();
JsonObject topicDetails = video.getAsJsonObject("topicDetails");
@@ -68,13 +69,18 @@ protected void calculateMusicCount(JsonArray videos) {
continue;
}
}
+ if (isMusic) {
+ // likedMusicHistory records what video is music
+ likedMusicHistory.add(firstVideoCount + i);
- if (isMusic && totalSubgenres == 0) {
+ if (totalSubgenres == 0) {
// video only classified as Music so we update as "Other music"
- this.updateGenre("Other music");
+ this.updateGenre("Other music");
+ }
}
+
}
- return;
+ return firstVideoCount + videos.size();
}
/**
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
index cc7b3fc8..e8886376 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
@@ -96,6 +96,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
JsonObject likedVideoRes;
JsonArray videos;
YoutubeGenres genreAnalysis = new YoutubeGenres();
+ int videosRetrieved = 0;
// next Page Token must be an empty string for first http call
String nextPageToken = "";
@@ -111,7 +112,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
}
videos = likedVideoRes.getAsJsonArray("items");
- genreAnalysis.calculateMusicCount(videos);
+ videosRetrieved =
+ genreAnalysis.calculateMusicCount(videosRetrieved, videos);
nextPageToken = getNextPageToken(likedVideoRes);
}
From d3dfb851c34292cad1181b5aa4d916058f334e70 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 11:57:27 -0400
Subject: [PATCH 03/11] added comments
---
client/js/genre.js | 1 +
.../java/com/google/musicanalysis/site/YoutubeGenres.java | 8 ++++++--
.../com/google/musicanalysis/site/YoutubeServlet.java | 5 +++--
3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/client/js/genre.js b/client/js/genre.js
index f9dffd51..360249ee 100644
--- a/client/js/genre.js
+++ b/client/js/genre.js
@@ -20,5 +20,6 @@ async function displayMusicGenre() {
const genreCount = await response.text();
genreBlock.innerHTML = genreCount;
+ console.log(JSON.parse(genreCount));
}
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
index 8fe7dee4..e9a6c62f 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
@@ -23,6 +23,8 @@ public class YoutubeGenres {
public HashMap genreData = new HashMap();
public int totalMusic = 0;
public int maxGenreCount = 0;
+ // element of value x means xth latest video is music
+ // needed for heat map
public ArrayList likedMusicHistory = new ArrayList();
public YoutubeGenres() {
@@ -32,7 +34,9 @@ public YoutubeGenres() {
/**
* parses through youtube liked videos json array,
* updates hash map to contain frequency count of each music genre
+ * @param firstVideoCount the number of videos retrieved before this http call
* @param videos json array of youtube liked videos
+ * @return number of videos retrieved so far
*/
protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
for (int i = 0; i < videos.size(); i++) {
@@ -69,8 +73,9 @@ protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
continue;
}
}
+
if (isMusic) {
- // likedMusicHistory records what video is music
+ // likedMusicHistory records video numbers that are music
likedMusicHistory.add(firstVideoCount + i);
if (totalSubgenres == 0) {
@@ -78,7 +83,6 @@ protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
this.updateGenre("Other music");
}
}
-
}
return firstVideoCount + videos.size();
}
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
index e8886376..1bafd6f3 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
@@ -96,6 +96,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
JsonObject likedVideoRes;
JsonArray videos;
YoutubeGenres genreAnalysis = new YoutubeGenres();
+ // needed to keep track of likedMusicHistory for heat map
int videosRetrieved = 0;
// next Page Token must be an empty string for first http call
@@ -112,8 +113,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
}
videos = likedVideoRes.getAsJsonArray("items");
- videosRetrieved =
- genreAnalysis.calculateMusicCount(videosRetrieved, videos);
+ videosRetrieved = genreAnalysis
+ .calculateMusicCount(videosRetrieved, videos);
nextPageToken = getNextPageToken(likedVideoRes);
}
From 9c7c25a514c17b7ae3f75a52b9cb447ec852f8bb Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 13:01:23 -0400
Subject: [PATCH 04/11] got rid of console.log
---
client/js/genre.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/client/js/genre.js b/client/js/genre.js
index 360249ee..f9dffd51 100644
--- a/client/js/genre.js
+++ b/client/js/genre.js
@@ -20,6 +20,5 @@ async function displayMusicGenre() {
const genreCount = await response.text();
genreBlock.innerHTML = genreCount;
- console.log(JSON.parse(genreCount));
}
From c9f12b4b250200378f16cf801bb6e6ffac2185c9 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 13:32:48 -0400
Subject: [PATCH 05/11] deleted console.log
---
client/js/genre.js | 1 -
1 file changed, 1 deletion(-)
diff --git a/client/js/genre.js b/client/js/genre.js
index f9dffd51..44426f89 100644
--- a/client/js/genre.js
+++ b/client/js/genre.js
@@ -21,4 +21,3 @@ async function displayMusicGenre() {
const genreCount = await response.text();
genreBlock.innerHTML = genreCount;
}
-
From b1f603e90202615da8a83b3e153d099a9aae5e05 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 30 Jul 2020 21:06:29 -0400
Subject: [PATCH 06/11] merge with master
---
client/css/bar.css | 60 ++++++++++++++++++++++++++++++++++++++++++++
client/js/bar.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 122 insertions(+)
create mode 100644 client/css/bar.css
create mode 100644 client/js/bar.js
diff --git a/client/css/bar.css b/client/css/bar.css
new file mode 100644
index 00000000..484961f3
--- /dev/null
+++ b/client/css/bar.css
@@ -0,0 +1,60 @@
+.hero {
+ display: grid;
+ align-content: center;
+ justify-items: center;
+ width: 100%; /* don't use 100vw, that will cause horizontal scrollbar */
+ height: 100vh;
+}
+
+.svg {
+ width: 100%;
+ height: 100%;
+}
+
+#vis {
+ display: flex;
+ align-items: stretch;
+ width: 50vh;
+
+ height: 60vh;
+ margin-left: 0;
+
+ background-color: #222425;
+}
+
+#graph {
+ display: inline-block;
+ width: 70%;
+}
+
+.bar {
+ cursor: pointer;
+
+ transition: fill .3s ease;
+
+ fill: var(--color-accent-primary-2);
+}
+
+.bar:hover, .bar:focus {
+ fill: var(--color-accent-special);
+}
+
+#bar-text {
+ display: flex;
+ flex-flow: column nowrap;
+ width: 25%;
+ height: 100%;
+
+ text-align: right;
+ vertical-align: top;
+}
+
+.category {
+ display: flex;
+ flex-basis: 0;
+ flex-direction: column;
+ flex-grow: 1;
+ justify-content: center;
+
+ text-align: right;
+}
diff --git a/client/js/bar.js b/client/js/bar.js
new file mode 100644
index 00000000..9b6f2f2b
--- /dev/null
+++ b/client/js/bar.js
@@ -0,0 +1,62 @@
+/**
+ * @file constructs bar graph from scratch
+ */
+
+// hard coded data for bar chart for now
+const CHART_VALUES = [1, 3, 1, 2];
+const CHART_CATEGORIES = [
+ 'Pop Music',
+ 'Other Music',
+ 'Electronic Music',
+ 'Music of Latin America',
+];
+
+const GRAPH_HEIGHT = 100;
+// each bar container is composed of bar padding and fill
+const BAR_PERCENT_FILL = 0.7;
+const BAR_PERCENT_PADDING = 1 - BAR_PERCENT_FILL;
+
+const GRAPH_LEFT_PADDING = 2.5;
+
+/**
+ * creates SVG bar chart given chart values and categories
+ * @param {number[]} chartValues array of bar values/lengths
+ * @param {string[]} chartCategories array of bar categories/labels
+ */
+function createBarChart(chartValues, chartCategories) {
+ const maxChartValues = Math.max(...chartValues);
+ const barContainerHeight = GRAPH_HEIGHT / chartValues.length;
+
+ const barThickness = BAR_PERCENT_FILL * barContainerHeight;
+ const barUnitLength = 100 / maxChartValues;
+
+ // top graph padding depends on bar padding
+ const graphTopPadding = (BAR_PERCENT_PADDING / 2) * barContainerHeight;
+
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ svg.setAttribute('viewBox', '0 0 100 100');
+ svg.setAttribute('preserveAspectRatio', 'none');
+ svg.setAttribute('class', 'svg');
+ document.getElementById('graph').appendChild(svg);
+
+ for (let i = 0; i < chartValues.length; i++) {
+ const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ svg.appendChild(g);
+ g.setAttribute('class', 'bar');
+
+ const bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ g.appendChild(bar);
+ bar.setAttribute('width', barUnitLength * chartValues[i]);
+ bar.setAttribute('height', barThickness);
+ bar.setAttribute('x', GRAPH_LEFT_PADDING);
+ bar.setAttribute('y', graphTopPadding + barContainerHeight * i);
+
+ const barTextContainer = document.getElementById('bar-text');
+ const category = document.createElement('div');
+ barTextContainer.appendChild(category);
+ category.setAttribute('class', 'category');
+ category.textContent = chartCategories[i];
+ }
+}
+
+createBarChart(CHART_VALUES, CHART_CATEGORIES);
From 4734a3e437b26ced7b0121d0af1617f9d452fe72 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Mon, 3 Aug 2020 15:52:58 -0400
Subject: [PATCH 07/11] changes to js/html to retrieve json
---
client/js/genre.js | 3 ++-
client/youtube-genre.html | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/client/js/genre.js b/client/js/genre.js
index 44426f89..f9c790cd 100644
--- a/client/js/genre.js
+++ b/client/js/genre.js
@@ -3,12 +3,13 @@
* and displays on youtube-genre.html
*/
-const genreBlock = document.getElementById('genres');
/**
* fetches genre count hashmap from /api/youtube and updates html
*/
async function displayMusicGenre() {
+ const genreBlock = document.getElementById('genres');
+
// keep track of num_videos in URL w/o reload
history.pushState('', '', `youtube-genre.html`);
diff --git a/client/youtube-genre.html b/client/youtube-genre.html
index c7d4cb87..2efa59b4 100644
--- a/client/youtube-genre.html
+++ b/client/youtube-genre.html
@@ -15,6 +15,7 @@ What music do you listen to on youtube?
+
From 2ea7481d657d6171324984eff8ea4879ebff24e9 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Mon, 3 Aug 2020 16:21:52 -0400
Subject: [PATCH 08/11] added comments
---
.../com/google/musicanalysis/site/YoutubeGenres.java | 11 ++++++-----
.../com/google/musicanalysis/site/YoutubeServlet.java | 6 ++++--
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
index e9a6c62f..bc0a632a 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeGenres.java
@@ -34,12 +34,13 @@ public YoutubeGenres() {
/**
* parses through youtube liked videos json array,
* updates hash map to contain frequency count of each music genre
- * @param firstVideoCount the number of videos retrieved before this http call
* @param videos json array of youtube liked videos
- * @return number of videos retrieved so far
+ * @param firstVideoCount the number of videos retrieved before this http call
+ * @return number of videos retrieved in this call
*/
- protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
- for (int i = 0; i < videos.size(); i++) {
+ protected int calculateMusicCount(JsonArray videos, int firstVideoCount) {
+ int videosSize = videos.size();
+ for (int i = 0; i < videosSize; i++) {
JsonObject video = videos.get(i).getAsJsonObject();
JsonObject topicDetails = video.getAsJsonObject("topicDetails");
@@ -84,7 +85,7 @@ protected int calculateMusicCount(int firstVideoCount, JsonArray videos) {
}
}
}
- return firstVideoCount + videos.size();
+ return videosSize;
}
/**
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
index 1bafd6f3..d1a5f541 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
@@ -101,6 +101,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
// next Page Token must be an empty string for first http call
String nextPageToken = "";
+ // make multiple calls to youtube API. A page token determines each call
while (nextPageToken != null) {
youtubeResBody = getYoutubeRes(API_KEY,
accessToken.toString(),
@@ -113,8 +114,9 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
}
videos = likedVideoRes.getAsJsonArray("items");
- videosRetrieved = genreAnalysis
- .calculateMusicCount(videosRetrieved, videos);
+ // videosRetrieved keeps track of music video order in calculateMusicCount
+ videosRetrieved += genreAnalysis
+ .calculateMusicCount(videos, videosRetrieved);
nextPageToken = getNextPageToken(likedVideoRes);
}
From 44c8c52226e2cfa85a8bf1778910b52ed362b657 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Mon, 3 Aug 2020 16:24:27 -0400
Subject: [PATCH 09/11] added comments
---
.../java/com/google/musicanalysis/site/YoutubeServlet.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
index d1a5f541..37ecbcfd 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
@@ -101,7 +101,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
// next Page Token must be an empty string for first http call
String nextPageToken = "";
- // make multiple calls to youtube API. A page token determines each call
+ // Make multiple paginated calls to youtube API.
+ // Each call has a new page token
while (nextPageToken != null) {
youtubeResBody = getYoutubeRes(API_KEY,
accessToken.toString(),
From 41b45e0165391e1931bf4dee30fb2782bdb4d185 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Mon, 3 Aug 2020 16:28:28 -0400
Subject: [PATCH 10/11] modified videosRetrieved comment for clarity
---
.../main/java/com/google/musicanalysis/site/YoutubeServlet.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
index 37ecbcfd..b61536b4 100644
--- a/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
+++ b/server/src/main/java/com/google/musicanalysis/site/YoutubeServlet.java
@@ -115,7 +115,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res)
}
videos = likedVideoRes.getAsJsonArray("items");
- // videosRetrieved keeps track of music video order in calculateMusicCount
+ // videosRetrieved keeps track of music video order in genreAnalysis
videosRetrieved += genreAnalysis
.calculateMusicCount(videos, videosRetrieved);
From f024c16659b4190ca71ff49228b3489ebfb2df39 Mon Sep 17 00:00:00 2001
From: Grace Tian
Date: Thu, 6 Aug 2020 15:21:12 -0400
Subject: [PATCH 11/11] delete num videos comment
---
client/js/genre.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/client/js/genre.js b/client/js/genre.js
index f9c790cd..37c53a87 100644
--- a/client/js/genre.js
+++ b/client/js/genre.js
@@ -10,9 +10,6 @@
async function displayMusicGenre() {
const genreBlock = document.getElementById('genres');
- // keep track of num_videos in URL w/o reload
- history.pushState('', '', `youtube-genre.html`);
-
const response = await fetch(`/api/youtube`);
if (response.status == 401) {
// no oauth login so redirect to new page