Browse Source

Draw audio feature bar charts

Started work on drawing the bar charts for audio features.
master
Chris Shyi 7 years ago
parent
commit
c518556126
  1. 5
      spotifyvis/admin.py
  2. 8
      spotifyvis/models.py
  3. 8
      spotifyvis/static/spotifyvis/scripts/user_data.js
  4. 63
      spotifyvis/templates/spotifyvis/user_data.html
  5. 5
      spotifyvis/utils.py
  6. 2
      spotifyvis/views.py

5
spotifyvis/admin.py

@ -1,3 +1,8 @@
from django.contrib import admin from django.contrib import admin
from .models import Track, Artist, AudioFeatures, User
# Register your models here. # Register your models here.
admin.site.register(Track)
admin.site.register(Artist)
admin.site.register(AudioFeatures)
admin.site.register(User)

8
spotifyvis/models.py

@ -51,10 +51,14 @@ class Track(models.Model):
runtime = models.PositiveSmallIntegerField() runtime = models.PositiveSmallIntegerField()
name = models.CharField(max_length=150) name = models.CharField(max_length=150)
users = models.ManyToManyField(User, blank=True) users = models.ManyToManyField(User, blank=True)
genre = models.CharField(max_length=30)
genre = models.CharField(max_length=30, default="")
def __str__(self): 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 # # }}} Track #

8
spotifyvis/static/spotifyvis/scripts/user_data.js

@ -2,8 +2,9 @@
* Retrieves data for a specific audio feature for a certain user * Retrieves data for a specific audio feature for a certain user
* @param audioFeature: the audio feature for which data will be retrieved * @param audioFeature: the audio feature for which data will be retrieved
* @param clientSecret: the client secret, needed for security * @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(); let httpRequest = new XMLHttpRequest();
/* /*
* Handler for the response * Handler for the response
@ -12,10 +13,7 @@ function getAudioFeatureData(audioFeature, userSecret) {
if (httpRequest.readyState === XMLHttpRequest.DONE) { if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) { if (httpRequest.status === 200) {
let responseData = JSON.parse(httpRequest.responseText); 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 { } else {
alert("There was a problem with the login request, please try again!"); alert("There was a problem with the login request, please try again!");
} }

63
spotifyvis/templates/spotifyvis/user_data.html

@ -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> <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]--> <![endif]-->
<p>Logged in as {{ id }}</p> <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 src="{% static "spotifyvis/scripts/user_data.js" %}"></script>
<script> <script>
sessionStorage.setItem('user_secret', "{{ user_secret }}"); 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> </script>
</body> </body>
</html> </html>

5
spotifyvis/utils.py

@ -401,9 +401,8 @@ def get_artists_in_genre(user, genre):
:returns: dict of artists in the genre along with the number of songs they :returns: dict of artists in the genre along with the number of songs they
have. have.
""" """
artist_counts = (Artist.objects.filter(track__users=user)
.filter(track__genre=genre)
# .annotate(num_songs=Count('track', filter=Q(track__genre=genre)))
artist_counts = (Artist.objects.filter(track__users=user).distinct()
.filter(track__genre=genre).distinct()
.annotate(num_songs=Count('track')) .annotate(num_songs=Count('track'))
) )
processed_artist_counts = [{'name': artist.name, 'num_songs': artist.num_songs} for artist in artist_counts] processed_artist_counts = [{'name': artist.name, 'num_songs': artist.num_songs} for artist in artist_counts]

2
spotifyvis/views.py

@ -165,7 +165,7 @@ def test_db(request):
"""TODO """TODO
""" """
# user_id = "polarbier" # user_id = "polarbier"
user_id = "35kxo00qqo9pd1comj6ylxjq7"
user_id = "chrisshyi13"
context = { context = {
'user_secret': User.objects.get(user_id=user_id).user_secret, 'user_secret': User.objects.get(user_id=user_id).user_secret,
} }

Loading…
Cancel
Save