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:
@@ -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))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user