diff --git a/.gitignore b/.gitignore index ed7cbb7..4b217f6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,12 @@ media/history/* spotifyvis/static/graphs/sass/* -*.pyc -*.log *.bak -*.txt +*.log *.map +*.orig +*.pyc +*.txt api-keys.sh db.sqlite3 diff --git a/README.md b/README.md index cbefa31..b20be0e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,11 @@ pip install --user pipenv python3 -m venv /path/to/new/virtual/environment ``` -3. `cd` into the directory you just created a virtual environment in, and clone the GitHub repo. +3. `cd` into the directory you just created a virtual environment in, and clone the GitHub repo: + +``` +git clone https://github.com/Kevin-Mok/spotify-lib-vis +``` 4. Activate the virtual environment from the command line. @@ -40,16 +44,10 @@ source bin/activate pip install -r requirements.txt ``` -6. Run Django migrations. - -``` -manage.py migrate -``` - -7. Start the server. +6. Run `reset_db.sh` to create the database and start the server. ``` -python manage.py runserver +cd src && ./reset_db.sh ``` diff --git a/graphs/static/graphs/scripts/artist_graph.js b/graphs/static/graphs/scripts/artist_graph.js index a01af92..18fa142 100644 --- a/graphs/static/graphs/scripts/artist_graph.js +++ b/graphs/static/graphs/scripts/artist_graph.js @@ -1,9 +1,81 @@ +const log = console.log +const width = 1366 +const height = 768 +// const width = 1000 +// const height = 500 + /** * Draws the artist count graph as a bubble chart, and appends it the a designated parent element * @param artistData: the artist counts data as an array of objects, of the format {'name': artist name, 'num_songs': 50} * @param parentElem: the DOM element to append the artist graph to (as a string) */ function drawArtistGraph(artistData, parentElem) { + // const color = d3.scaleOrdinal(d3.schemeCategory10); + const color = d3.scaleOrdinal().range(randomColor({//{{{ + count: Object.keys(artistData.children).length, + luminosity: 'light', + }))//}}} + + const svg = d3.select(parentElem)//{{{ + // const svg = d3.select(DOM.svg(width, height)) + .append("div") + .classed("svg-container", true) //container class to make it responsive + .append("svg") + //responsive SVG needs these 2 attributes and no width and height attr + .attr("preserveAspectRatio", "xMinYMin meet") + .attr("viewBox", `0 0 ${width} ${height}`) + //class to make it responsive + .classed("svg-content-responsive", true) + .style("width", "100%") + .style("height", "100%") + .attr("font-size", 12) + .attr("text-anchor", "middle")//}}} + + const root = d3.pack()//{{{ + .size([width - 2, height - 2]) + .padding(3) + (d3.hierarchy(artistData) + .sum(d => d.num_songs)) + + const leaf = svg.selectAll("g") + .data(root.leaves()) + .join("g") + .attr("transform", d => `translate(${d.x + 1},${d.y + 1})`);//}}} + + leaf.append("circle")//{{{ + .attr("r", d => d.r) + // .attr("fill-opacity", 0.9) + .attr("fill", (d, id) => color(id))//}}} + + leaf.append("text")//{{{ + .selectAll("tspan") + .data(d => d.data.name.split(/\s/g).concat([d.data.num_songs])) + .join("tspan") + .attr("x", 0) + .attr("y", (d, i, nodes) => `${i - nodes.length / 2 + 0.8}em`) + // .attr("fill", "white") + .text(d => d)//}}} + + // hover text {{{ // + leaf.append("title") + .text(d => `${d.data.name}: ${d.data.num_songs}`) + // }}} hover text // + + // graph title {{{ // + svg.append("text") + .attr('x', (width / 2.2)) + .attr('y', 50) + .attr('fill', "white") + .attr('text-anchor', 'middle') + .attr("font-weight", "bold") + .attr("font-size", 28) + .text('Artists in Library'); + // }}} graph title // + + return svg.node(); +} + +function drawArtistGraphOld(artistData, parentElem) {//{{{ let margin = {top: 20, right: 30, bottom: 30, left: 40}; // let width = 1000 - margin.right - margin.left; // let height = 1000 - margin.top - margin.bottom; @@ -36,7 +108,7 @@ function drawArtistGraph(artistData, parentElem) { .append("svg") //responsive SVG needs these 2 attributes and no width and height attr .attr("preserveAspectRatio", "xMinYMin meet") - .attr("viewBox", "0 0 600 250") + .attr("viewBox", "0 0 1024 768") //class to make it responsive .classed("svg-content-responsive", true); @@ -61,9 +133,7 @@ function drawArtistGraph(artistData, parentElem) { }); node.append("circle") - .attr("r", function(d) { - return d.r; - }) + .attr("r", d => d.r) .style("fill", function(d,i) { return color(i); }); @@ -73,7 +143,8 @@ function drawArtistGraph(artistData, parentElem) { .attr("dy", ".2em") .style("text-anchor", "middle") .text(function(d) { - return d.data.name.substring(0, d.r / 3); + return d.data.name.substring(0, d.r / 1.5); + // return formatArtistName(d.data.name) }) .attr("font-family", "sans-serif") .attr("font-size", function(d){ @@ -97,7 +168,4 @@ function drawArtistGraph(artistData, parentElem) { d3.select(self.frameElement) // .style("height", height + "px"); .style("height", "100%") - - - -} +}//}}} diff --git a/graphs/static/graphs/scripts/genre_graph.js b/graphs/static/graphs/scripts/genre_graph.js index 1e9380f..66f8f24 100644 --- a/graphs/static/graphs/scripts/genre_graph.js +++ b/graphs/static/graphs/scripts/genre_graph.js @@ -41,6 +41,8 @@ function create_genre_graph(data) { // hue: '#00ced1', hue: '#0099CC', })); + // colorScale = d3.scaleOrdinal(d3.schemeCategory10); + // colorScale = d3.scaleOrdinal(d3.schemeDark2); // }}} setup bar colors // diff --git a/graphs/templates/graphs/artist_graph.html b/graphs/templates/graphs/artist_graph.html index 3627250..fb7a8ac 100644 --- a/graphs/templates/graphs/artist_graph.html +++ b/graphs/templates/graphs/artist_graph.html @@ -8,20 +8,22 @@ + {% comment %} {% endcomment %} + + +
- - diff --git a/graphs/templates/graphs/genre_graph.html b/graphs/templates/graphs/genre_graph.html index fb75842..21d93d6 100644 --- a/graphs/templates/graphs/genre_graph.html +++ b/graphs/templates/graphs/genre_graph.html @@ -15,13 +15,13 @@ + + - - {% load static %} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..43a76ab --- /dev/null +++ b/requirements.txt @@ -0,0 +1,40 @@ +astroid==2.2.5 +backports.csv==1.0.7 +certifi==2019.3.9 +chardet==3.0.4 +defusedxml==0.5.0 +Django==2.2 +django-appconf==1.0.3 +django-compressor==2.2 +django-crispy-forms==1.7.2 +django-filter==2.1.0 +django-sass-processor==0.7.3 +django-tables2==2.0.6 +djangorestframework==3.9.2 +et-xmlfile==1.0.1 +idna==2.8 +isort==4.3.17 +jdcal==1.4 +lazy-object-proxy==1.3.1 +libsass==0.18.0 +mccabe==0.6.1 +odfpy==1.4.0 +openpyxl==2.6.2 +psycopg2==2.8.2 +psycopg2-binary==2.8.2 +pylint==2.3.1 +python-dateutil==2.8.0 +pytz==2019.1 +PyYAML==5.1 +rcssmin==1.0.6 +requests==2.21.0 +rjsmin==1.0.12 +six==1.12.0 +sqlparse==0.3.0 +tablib==0.13.0 +typed-ast==1.3.1 +unicodecsv==0.14.1 +urllib3==1.24.1 +wrapt==1.11.1 +xlrd==1.2.0 +xlwt==1.3.0 diff --git a/scripts/update-history.sh b/scripts/update-history.sh index 3e92f41..cabf955 100755 --- a/scripts/update-history.sh +++ b/scripts/update-history.sh @@ -1,3 +1,4 @@ #!/bin/bash -/home/kevin/coding/spotify-lib-vis/bin/python /home/kevin/coding/spotify-lib-vis/src/manage.py update-history >> /home/kevin/coding/spotify-lib-vis/src/api/management/commands/update-history.log +# /home/kevin/coding/spotify-lib-vis/bin/python /home/kevin/coding/spotify-lib-vis/src/manage.py update-history >> /home/kevin/coding/spotify-lib-vis/src/api/management/commands/update-history.log 2>&1 +python /home/kevin/coding/spotify-lib-vis/src/manage.py update-history >> /home/kevin/coding/spotify-lib-vis/src/api/management/commands/update-history.log 2>&1 diff --git a/todo.md b/todo.md new file mode 100644 index 0000000..566aa5a --- /dev/null +++ b/todo.md @@ -0,0 +1,7 @@ +- genre graph + - convert to bar graph + - sizing + - ordering +- loading/progress indicator +- change js tabs to 2 spaces +- Heroku? diff --git a/upgrade-pip-reqs.sh b/upgrade-pip-reqs.sh new file mode 100755 index 0000000..e4a227e --- /dev/null +++ b/upgrade-pip-reqs.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U +pip freeze --local > requirements.txt