Draw audio feature bar charts
Started work on drawing the bar charts for audio features.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from .models import Track, Artist, AudioFeatures, User
|
||||
|
||||
# Register your models here.
|
||||
admin.site.register(Track)
|
||||
admin.site.register(Artist)
|
||||
admin.site.register(AudioFeatures)
|
||||
admin.site.register(User)
|
||||
|
||||
@@ -51,10 +51,14 @@ class Track(models.Model):
|
||||
runtime = models.PositiveSmallIntegerField()
|
||||
name = models.CharField(max_length=150)
|
||||
users = models.ManyToManyField(User, blank=True)
|
||||
genre = models.CharField(max_length=30)
|
||||
genre = models.CharField(max_length=30, default="")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
track_str = "{}, genre: {}, artists: [".format(self.name, self.genre)
|
||||
for artist in self.artists.all():
|
||||
track_str += "{}, ".format(artist.name)
|
||||
track_str += "]"
|
||||
return track_str
|
||||
|
||||
# }}} Track #
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* Retrieves data for a specific audio feature for a certain user
|
||||
* @param audioFeature: the audio feature for which data will be retrieved
|
||||
* @param clientSecret: the client secret, needed for security
|
||||
* @param chartElement: the SVG element in which the data will be plotted
|
||||
*/
|
||||
function getAudioFeatureData(audioFeature, userSecret) {
|
||||
function plotAudioFeatureData(audioFeature, userSecret, chartElement) {
|
||||
let httpRequest = new XMLHttpRequest();
|
||||
/*
|
||||
* Handler for the response
|
||||
@@ -12,10 +13,7 @@ function getAudioFeatureData(audioFeature, userSecret) {
|
||||
if (httpRequest.readyState === XMLHttpRequest.DONE) {
|
||||
if (httpRequest.status === 200) {
|
||||
let responseData = JSON.parse(httpRequest.responseText);
|
||||
// TODO: The data points need to be plotted instead
|
||||
for (let data of responseData.data_points) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
} else {
|
||||
alert("There was a problem with the login request, please try again!");
|
||||
}
|
||||
|
||||
@@ -16,10 +16,71 @@
|
||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
|
||||
<![endif]-->
|
||||
<p>Logged in as {{ id }}</p>
|
||||
<script src="https://d3js.org/d3.v5.js"></script>
|
||||
<script src="{% static "spotifyvis/scripts/user_data.js" %}"></script>
|
||||
<script>
|
||||
sessionStorage.setItem('user_secret', "{{ user_secret }}");
|
||||
getAudioFeatureData('instrumentalness', sessionStorage.getItem('user_secret'));
|
||||
let width = 480, height = 300;
|
||||
|
||||
let instrumData = {
|
||||
"0-0.25": 0,
|
||||
"0.25-0.5": 0,
|
||||
"0.5-0.75": 0,
|
||||
"0.75-1.0": 0,
|
||||
};
|
||||
// define the vertical scaling function
|
||||
let vScale = d3.scaleLinear().range([height, 0]);
|
||||
|
||||
// getAudioFeatureData('instrumentalness', sessionStorage.getItem('user_secret'));
|
||||
d3.json("{% url 'get_audio_feature_data' audio_feature='instrumentalness' client_secret=user_secret %}")
|
||||
.then(function(response) {
|
||||
for (let dataPoint of response.data_points) {
|
||||
dataPoint = parseFloat(dataPoint);
|
||||
if (dataPoint > 0.75) {
|
||||
instrumData["0.75-1.0"] += 1;
|
||||
} else if (dataPoint > 0.5) {
|
||||
instrumData["0.5-0.75"] += 1;
|
||||
} else if (dataPoint > 0.25) {
|
||||
instrumData["0.25-0.5"] += 1;
|
||||
} else {
|
||||
instrumData["0-0.25"] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let dataSet = Object.values(instrumData);
|
||||
let dataRanges = Object.keys(instrumData); // Ranges of audio features, e.g. 0-0.25, 0.25-0.5, etc
|
||||
let dataArr = [];
|
||||
// turn the counts into an array of objects, e.g. {range: "0-0.25", counts: 5}
|
||||
for (let i = 0; i < dataRanges.length; i++) {
|
||||
dataArr.push({
|
||||
range: dataRanges[i],
|
||||
counts: instrumData[dataRanges[i]]
|
||||
});
|
||||
}
|
||||
vScale.domain([0, d3.max(dataSet)]);
|
||||
|
||||
let hScale = d3.scaleBand().domain(dataRanges).rangeRound([0, width]);
|
||||
|
||||
let barWidth = width / dataSet.length;
|
||||
|
||||
let instrumSVG = d3.select('body')
|
||||
.append('svg').attr('width', width).attr('height', height);
|
||||
|
||||
let xAxis = d3.axisBottom().scale(hScale);
|
||||
let yAxis = d3.axisLeft().scale(vScale);
|
||||
|
||||
let instrumBar = instrumSVG.selectAll('g')
|
||||
.data(dataArr)
|
||||
.enter().append('g')
|
||||
.attr("transform", function(d) { return "translate(" + hScale(d.range) + ",0)"; });
|
||||
|
||||
instrumBar.append('rect')
|
||||
.attr('y', function(d) { return vScale(d.counts); })
|
||||
.attr("height", function(d) { return height - vScale(d.counts); })
|
||||
.attr("width", function(d) { return hScale(d.range); });
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -401,11 +401,10 @@ def get_artists_in_genre(user, genre):
|
||||
:returns: dict of artists in the genre along with the number of songs they
|
||||
have.
|
||||
"""
|
||||
artist_counts = (Artist.objects.filter(track__users=user)
|
||||
.filter(track__genre=genre)
|
||||
# .annotate(num_songs=Count('track', filter=Q(track__genre=genre)))
|
||||
.annotate(num_songs=Count('track'))
|
||||
)
|
||||
artist_counts = (Artist.objects.filter(track__users=user).distinct()
|
||||
.filter(track__genre=genre).distinct()
|
||||
.annotate(num_songs=Count('track'))
|
||||
)
|
||||
processed_artist_counts = [{'name': artist.name, 'num_songs': artist.num_songs} for artist in artist_counts]
|
||||
# pprint.pprint(processed_artist_counts)
|
||||
return processed_artist_counts
|
||||
|
||||
@@ -165,7 +165,7 @@ def test_db(request):
|
||||
"""TODO
|
||||
"""
|
||||
# user_id = "polarbier"
|
||||
user_id = "35kxo00qqo9pd1comj6ylxjq7"
|
||||
user_id = "chrisshyi13"
|
||||
context = {
|
||||
'user_secret': User.objects.get(user_id=user_id).user_secret,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user