Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vanilla bars w/ BACKEND DATA!! #74

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions client/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
"google"
],
"env": {
"browser": true
"browser": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2020
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"jsdoc"
Expand Down Expand Up @@ -47,7 +49,6 @@
"jsdoc/require-returns-description": ["warn"],
"jsdoc/valid-types": ["warn"],
"new-cap": ["off"],
"indent": ["warn", 2],
"max-len": ["warn", { "code": 80 }]
},
"settings": {
Expand All @@ -57,7 +58,8 @@
"message": "@extends is to be used over @augments as it is more evocative of classes than @augments",
"replacement": "extends"
}
}
},
"mode": "typescript"
}
}
}
34 changes: 17 additions & 17 deletions client/js/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,44 @@
* @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',
];
import {SVG_NS} from '/js/util.js';
import {GENRE_ANALYSIS} from '/js/genre.js';

const GRAPH_HEIGHT = 100;
const GRAPH_LEFT_PADDING = 2.5;

// 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
* @param {number} maxChartVal largest value of chartValues
*/
function createBarChart(chartValues, chartCategories) {
const maxChartValues = Math.max(...chartValues);
function createBarChart(chartValues, chartCategories, maxChartVal) {
const barContainerHeight = GRAPH_HEIGHT / chartValues.length;

const barThickness = BAR_PERCENT_FILL * barContainerHeight;
const barUnitLength = 100 / maxChartValues;
const barUnitLength = 100 / maxChartVal;

// 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');
const svg = document.createElementNS(SVG_NS, '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');
const g = document.createElementNS(SVG_NS, 'g');
svg.appendChild(g);
g.setAttribute('class', 'bar');

const bar = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
const bar = document.createElementNS(SVG_NS, 'rect');
g.appendChild(bar);
bar.setAttribute('width', barUnitLength * chartValues[i]);
bar.setAttribute('height', barThickness);
Expand All @@ -59,4 +54,9 @@ function createBarChart(chartValues, chartCategories) {
}
}

createBarChart(CHART_VALUES, CHART_CATEGORIES);
GENRE_ANALYSIS.then((DATA) => {
createBarChart(
Object.values(DATA.genreData),
Object.keys(DATA.genreData),
DATA.maxGenreCount);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if Object.values and Object.keys is the best way to do it

I assume that the array returned from both methods should match up with each other

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they match up then I think this is a clever-ish solution to your problem. You could also just change createBarChart to accept the entire map and then loop through the key-value pairs there. I personally prefer the second method, but I'd also like to see what @laptou has to say about it.

});
17 changes: 10 additions & 7 deletions client/js/genre.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
/**
* fetches youtube api calls from YoutubeServlet.java
* @file fetches youtube api calls from YoutubeServlet.java
* and displays on youtube-genre.html
*/

const genreBlock = document.getElementById('genres');
document.body.onload = fetchMusicGenre();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you calling fetchMusicGenre() as an onload handler if you call it on line 24?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O good point


/**
* fetches genre count hashmap from /api/youtube and updates html
* fetches and returns genre analysis object from /api/youtube
*
* @returns {JSON object} of youtube genreData and stats
*/
async function displayMusicGenre() {
async function fetchMusicGenre() {
// keep track of num_videos in URL w/o reload
history.pushState('', '', `youtube-genre.html`);
history.pushState('', '', 'youtube-genre.html');

const response = await fetch(`/api/youtube`);
const response = await fetch('/api/youtube');
if (response.status == 401) {
// no oauth login so redirect to new page
window.open('/api/oauth/login/youtube');
}

const genreCount = await response.text();
genreBlock.innerHTML = genreCount;
return JSON.parse(genreCount);
}

export const GENRE_ANALYSIS = fetchMusicGenre();
17 changes: 17 additions & 0 deletions client/js/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Delays an async function.
*
* @param {number} ms The number of milliseconds to wait before resolving the
* Promise.
* @returns {Promise<void>} A Promise which resolves after a delay.
*/
export async function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

/**
* The namespace of SVG elements.
*
* @type {'http://www.w3.org/2000/svg'}
*/
export const SVG_NS = 'http://www.w3.org/2000/svg';
17 changes: 8 additions & 9 deletions client/youtube-genre.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@

</head>
<body>
<div id="content">
<h1>What music do you listen to on youtube?</h1>
<div id="numVideoForm">
<p>
<input type="submit" onclick="displayMusicGenre()"/>
</p>
</div>
<div class="title hero" id="banner">
<h1>What music do you listen to on YouTube? </h1>
<p>
<button type="submit" onclick="fetchMusicGenre()" class="btn"/>Find Out!</button>
</p>
<div id="genres"></div>
</div>
<main>
<div class='hero'>
Expand All @@ -26,6 +25,6 @@ <h1>Youtube Genre Bar Chart</h1>
</div>
</main>
</body>
<script src="js/genre.js"></script>
<script src="js/bar.js"></script>
<script type="module" src="js/genre.js"></script>
<script type="module" src="js/bar.js"></script>
</html>