Fixed bars not being at right height

Avoided artist breakdown overflowing total tracks in genre by only
adding artists while running tally is less than total.
This commit is contained in:
2018-06-14 06:38:30 -04:00
parent 162b2dad37
commit f71ba20116
3 changed files with 16 additions and 8 deletions

View File

@@ -22,8 +22,6 @@
<svg width="960" height="500"></svg> <svg width="960" height="500"></svg>
<script> <script>
// {{{ setup
var svg = d3.select("svg"), var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 40}, margin = {top: 20, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right, width = +svg.attr("width") - margin.left - margin.right,
@@ -36,8 +34,6 @@
var y = d3.scaleLinear() var y = d3.scaleLinear()
.rangeRound([height, 0]); .rangeRound([height, 0]);
// }}}
d3.json("{% url "get_genre_data" user_secret %}").then(function(data) { d3.json("{% url "get_genre_data" user_secret %}").then(function(data) {
// convert strings to nums // convert strings to nums
data.forEach(function(d) { data.forEach(function(d) {
@@ -54,6 +50,7 @@
data.sort(function(a, b) { return b.num_songs - a.num_songs; }); data.sort(function(a, b) { return b.num_songs - a.num_songs; });
x.domain(data.map(function(d) { return d.genre; })); x.domain(data.map(function(d) { return d.genre; }));
y.domain([0, d3.max(data, function(d) { return d.num_songs; }) * 1.25]).nice(); y.domain([0, d3.max(data, function(d) { return d.num_songs; }) * 1.25]).nice();
//y.domain([0, d3.max(data, function(d) { return d.num_songs; })]).nice();
// setup bar colors // setup bar colors
var max_artists = d3.max(data, function(d) { var max_artists = d3.max(data, function(d) {
@@ -84,7 +81,7 @@
.data(stack) .data(stack)
.enter().append("rect") .enter().append("rect")
.attr("x", x(genre_dict.genre)) .attr("x", x(genre_dict.genre))
.attr("y", function(d) { return y(d.data[0]); }) .attr("y", function(d) { return y(d.data[1]); })
.attr("height", d => y(d.data[0]) - y(d.data[1])) .attr("height", d => y(d.data[0]) - y(d.data[1]))
.attr("width", x.bandwidth()) .attr("width", x.bandwidth())
.attr('fill', (d, i) => z(i)) .attr('fill', (d, i) => z(i))

View File

@@ -394,10 +394,13 @@ def process_library_stats(library_stats):
# get_artists_in_genre {{{ # # get_artists_in_genre {{{ #
def get_artists_in_genre(user, genre): def get_artists_in_genre(user, genre, max_songs):
"""Return count of artists in genre. """Return count of artists in genre.
:user: User object to return data for.
:genre: genre to count artists for. :genre: genre to count artists for.
:max_songs: max total songs to include to prevent overflow due to having
multiple artists on each track.
: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.
@@ -405,9 +408,16 @@ def get_artists_in_genre(user, genre):
artist_counts = (Artist.objects.filter(track__users=user) artist_counts = (Artist.objects.filter(track__users=user)
.filter(track__genre=genre) .filter(track__genre=genre)
.annotate(num_songs=Count('track', distinct=True)) .annotate(num_songs=Count('track', distinct=True))
.order_by('-num_songs')
) )
processed_artist_counts = {}
songs_added = 0
for artist in artist_counts:
if songs_added + artist.num_songs <= max_songs:
processed_artist_counts[artist.name] = artist.num_songs
songs_added += artist.num_songs
# 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]
processed_artist_counts = {artist.name: artist.num_songs for artist in artist_counts} # processed_artist_counts = {artist.name: artist.num_songs for artist in artist_counts}
# pprint.pprint(processed_artist_counts) # pprint.pprint(processed_artist_counts)
return processed_artist_counts return processed_artist_counts

View File

@@ -222,7 +222,8 @@ def get_genre_data(request, user_secret):
.annotate(num_songs=Count('genre')) .annotate(num_songs=Count('genre'))
) )
for genre_dict in genre_counts: for genre_dict in genre_counts:
genre_dict['artists'] = get_artists_in_genre(user, genre_dict['genre']) genre_dict['artists'] = get_artists_in_genre(user, genre_dict['genre'],
genre_dict['num_songs'])
pprint.pprint(list(genre_counts)) pprint.pprint(list(genre_counts))
return JsonResponse(data=list(genre_counts), safe=False) return JsonResponse(data=list(genre_counts), safe=False)