Continued updates for /enthusiast draft

This commit is contained in:
walkews 2017-07-14 16:08:27 -05:00
parent 04e8135cf0
commit e82149c072
7 changed files with 184 additions and 18 deletions

View file

@ -26,8 +26,11 @@ app = Flask(__name__)
CORS(app)
api_blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(api_blueprint, title='pyDataVizday api',
default='pyDataVizDay',
description='This api is used for the pyDataVizDay visualization',
doc='/doc/')
doc='/doc/',
version='0.0.1'
)
app.register_blueprint(api_blueprint)
parser = reqparse.RequestParser()
@ -50,6 +53,20 @@ dropdowns = {'genre': data.genre.genres.dropna().drop_duplicates().values.tolist
'language':data.movie.language.dropna().drop_duplicates().values.tolist()
}
def return_csv(df, filename='data.csv'):
try:
s_buf = io.StringIO()
df.to_csv(s_buf)
response = make_response(s_buf.getvalue())
cd = 'attachment; filename={}.csv'.format(filename)
response.headers['Content-Disposition'] = cd
response.mimetype = 'text/csv'
except AttributeError:
response = 'AttributeError'
return response
@app.route('/')
def index():
return render_template('index.html', body='Hello')
@ -121,6 +138,23 @@ class keywords(Resource):
return jsonify(words)
@api.route('/top_movies')
@api.expect(parser)
class top_movies(Resource):
def get(self):
args = parser.parse_args()
data = filter_with_args(args)
df = (data.movie
.sort_values('imdb_score', ascending=False)
.drop_duplicates(subset=['movie_title'])
.set_index('movie_title')
[['title_year', 'imdb_score', 'gross']]
.head(6)
)
return jsonify(df.to_json())
@api.route('/score_timeseries')
@api.expect(parser)
class score_timeseries(Resource):
@ -148,13 +182,22 @@ class score_timeseries(Resource):
['x'] + df.DATE.astype(str).values.tolist()],
# ['x'] + df.index.values.tolist()],
'colors':{
'IMDB Score': '#6998A6',
'gross': '#966001',
'IMDB Score': '#B80000',
'gross': '#fd8d3c',
'x': '#08414C'
}}
return jsonify(score_timeseries)
@api.route('/download')
@api.expect(parser)
class download(Resource):
def get(self):
args = parser.parse_args()
data = filter_with_args(args)
df = data.movie
return return_csv(df, 'movie.csv')
if __name__ == '__main__':
app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True

View file

@ -3,7 +3,7 @@ body{
/*font-size:16px;*/
}
.kpi {
color: #B80000;
/* color: #B80000; */
font-weight:10;
}
@ -44,3 +44,15 @@ body{
float: none;
margin: 0 auto;
}
.title{
font-size:22px;
color:#B80000;
font: bold;
}
.sentiment-chart{
text-align: center;
vertical-align: middle;
line-height: 200px;
}

View file

@ -1,5 +1,8 @@
var score_timeseries = document.getElementById('timeseries');
var mil = d3.format('$.3s')
var update_freq = 200
var data = {
'size': {
'height': 300
@ -23,8 +26,8 @@ var data = {
]
],
'colors': {
'IMDB Score': '#6998A6',
'gross': '#966001',
'IMDB Score': '#B80000',
'gross': '#fd8d3c',
'x': '#08414C'
}
},
@ -74,8 +77,13 @@ var data = {
$('#year').html(year)
$('#score').html(score)
$('#gross').html(gross)
update_words_year(year)
t = data
if ((performance.now() - window.last_update)>update_freq)
{
window.last_update = performance.now()
var year = data[0]['x'].getYear()+1900
update_words_year(year)
update_top_movies(String(parseInt(year) - 1), String(parseInt(year) + 1))
}
}
}
};
@ -110,6 +118,7 @@ $('#country').change(function(){update_all()})
$('#genre').change(function(){update_all()})
$('#start_year').change(function(){update_all()})
$('#end_year').change(function(){update_all()})
$('#download').click(function(){download()})
jQuery(document).ready(function(){
jQuery(".chosen").chosen();
@ -117,22 +126,34 @@ jQuery(document).ready(function(){
$('#word_cloud').jQCloud([{'text':'pyDataVizDay', 'weight':1}], word_coud_settings)
update_all()
});
function download(){
url = url_params('/api/download?')
window.location = url
}
function update_all(){
update_words()
update_ts()
update_top_movies()
last_update = performance.now()
}
function url_params(base)
function url_params(base, start_year_val, end_year_val)
{
// start_year = typeof start_year_val !== 'undefined' ? start_year.val()
var start_year_val = typeof start_year_val !== 'undefined' ? start_year_val: start_year.val()
var end_year_val = typeof end_year_val !== 'undefined' ? end_year_val: end_year.val()
var url = base
if (_top.val().length>0){url = url + 'top=' + _top.val() + '&'}
if (language.val().length>0){url = url + 'language=' + language.val() + '&'}
if (country.val().length>0){url = url + 'country=' + country.val() + '&'}
if (genre.val().length>0){url = url + 'genre=' + genre.val() + '&'}
if (start_year.val().length>0){url = url + 'start_year=' + start_year.val() + '&'}
if (end_year.val().length>0){url = url + 'end_year=' + end_year.val() + '&'}
if (start_year_val>0){url = url + 'start_year=' + String(start_year_val) + '&'}
if (end_year_val>0){url = url + 'end_year=' + String(end_year_val) + '&'}
return url
}
@ -165,6 +186,51 @@ function update_words()
})
}
poster_img = '';
function poster(title){
console.log(title)
var info = $.get('http://www.omdbapi.com/?t=' + title + '&apikey=90424a9e')
return info.done( function(){
poster_img = '<img src=' + info.responseJSON['Poster'] + '>'
console.log(poster_img)
return poster_img
}
)
}
function update_top_movies(start_year, end_year)
{
var url = url_params('/api/top_movies?', start_year, end_year)
var top_movies = $.get(url)
var promises = []
top_movies.done(function()
{
tm = JSON.parse(top_movies.responseJSON)
h = ''
for (title in tm['gross']) {
// console.log(title)
var info = $.get('http://www.omdbapi.com/?t=' + title + '&apikey=90424a9e')
promises.push(info)
}
$.when.apply(null, promises).done(function(){
// console.log(promises)
window.promises = promises
for (i in promises){
console.log()
h = promises[i].responseJSON['Title'] + '<br> <img src=' + promises[i].responseJSON['Poster'] + '><br><br>'
$('#poster-' + i).html('<img src=' + promises[i].responseJSON['Poster'] + '>')
$('#title-' + i).html(promises[i].responseJSON['Title'])
}
// $('#top_movies').html(h)
// console.log(h)
})
// console.log(poster(title))
}
)
}

View file

@ -25,7 +25,11 @@
</div>
</div>
{% endfor %}
<div class="col-sm-1">
<button id='download' class="glyphicon glyphicon-download-alt"></button>
</div>
</div>
</div>
</div>

View file

@ -6,7 +6,7 @@
<!-- Load d3.js and c3.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.4/jqcloud.css">
<script src='http://d3js.org/d3.v3.min.js' charset='utf-8'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/c3/0.4.8/c3.min.js'></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="static/node_modules/chosen-js/chosen.css">
<script src="static/node_modules/chosen-js/chosen.jquery.js"></script>
@ -28,11 +28,11 @@
</div>
</div>
<div class='col-sm-1'>
Score: <div class='kpi' id='score'>
Score: <div class='kpi' id='score' style='color:#B80000'>
</div>
</div>
<div class='col-sm-4'>
Gross: <div class='kpi' id='gross' style='color:green'>
Gross: <div class='kpi' id='gross' style='color:#4D9913'>
</div>
<div class='col-sm-9'></div>
</div>
@ -45,10 +45,39 @@
</div>
<div class="row" min-height:150px>
<div class='col-sm-6 centered'>
<div class='col-sm-6'>
<div id='sentiment-chart' class='sentiment-chart'><h2>SENTIMENT</h2></div>
</div>
<div class='col-sm-6'>
<div id='word_cloud'></div>
</div>
</div>
<div class="row" min-height:150px>
<div class='col-sm-6 centered'>
<div id='top_movies'></div>
</div>
</div>
<div class='row' padding:50px>
<div class='col-sm-3'></div>
<div class='col-sm-6' style='text-align:center'>
<h2>Top Movies</h2>
</div>
<div class='col-sm-3'></div>
</div>
{% for i in range(0, 6, 3) %}
<div class="row" min-height:150px>
{% for j in range(3) %}
<div class='col-sm-4'>
<div id='title-{{i+j}}' class='title'></div>
<div id='poster-{{ i + j }}' class='poster'></div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
<script src='static/js/enthusiast.js'></script>
{% endblock %}

View file

@ -9,7 +9,7 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href='https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.8/c3.min.css' rel='stylesheet' type='text/css'/>
<link href='https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css' rel='stylesheet' type='text/css'/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

View file

@ -5,6 +5,18 @@
----
# Agenda
1. Viz Walk (3 Views)
1. Full Web App
* Simple Web App
* Exploritory Notebook
* Tools Used
* Other Considerations
* Pros/Cons
----
# Open The Viz
[pydatavizday.herokuapp.com](pydatavizday.herokuapp.com)