Continued updates for /enthusiast draft
This commit is contained in:
parent
04e8135cf0
commit
e82149c072
7 changed files with 184 additions and 18 deletions
|
|
@ -26,8 +26,11 @@ app = Flask(__name__)
|
||||||
CORS(app)
|
CORS(app)
|
||||||
api_blueprint = Blueprint('api', __name__, url_prefix='/api')
|
api_blueprint = Blueprint('api', __name__, url_prefix='/api')
|
||||||
api = Api(api_blueprint, title='pyDataVizday api',
|
api = Api(api_blueprint, title='pyDataVizday api',
|
||||||
|
default='pyDataVizDay',
|
||||||
description='This api is used for the pyDataVizDay visualization',
|
description='This api is used for the pyDataVizDay visualization',
|
||||||
doc='/doc/')
|
doc='/doc/',
|
||||||
|
version='0.0.1'
|
||||||
|
)
|
||||||
app.register_blueprint(api_blueprint)
|
app.register_blueprint(api_blueprint)
|
||||||
|
|
||||||
parser = reqparse.RequestParser()
|
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()
|
'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('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return render_template('index.html', body='Hello')
|
return render_template('index.html', body='Hello')
|
||||||
|
|
@ -121,6 +138,23 @@ class keywords(Resource):
|
||||||
|
|
||||||
return jsonify(words)
|
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.route('/score_timeseries')
|
||||||
@api.expect(parser)
|
@api.expect(parser)
|
||||||
class score_timeseries(Resource):
|
class score_timeseries(Resource):
|
||||||
|
|
@ -148,13 +182,22 @@ class score_timeseries(Resource):
|
||||||
['x'] + df.DATE.astype(str).values.tolist()],
|
['x'] + df.DATE.astype(str).values.tolist()],
|
||||||
# ['x'] + df.index.values.tolist()],
|
# ['x'] + df.index.values.tolist()],
|
||||||
'colors':{
|
'colors':{
|
||||||
'IMDB Score': '#6998A6',
|
'IMDB Score': '#B80000',
|
||||||
'gross': '#966001',
|
'gross': '#fd8d3c',
|
||||||
'x': '#08414C'
|
'x': '#08414C'
|
||||||
}}
|
}}
|
||||||
|
|
||||||
return jsonify(score_timeseries)
|
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__':
|
if __name__ == '__main__':
|
||||||
app.jinja_env.auto_reload = True
|
app.jinja_env.auto_reload = True
|
||||||
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ body{
|
||||||
/*font-size:16px;*/
|
/*font-size:16px;*/
|
||||||
}
|
}
|
||||||
.kpi {
|
.kpi {
|
||||||
color: #B80000;
|
/* color: #B80000; */
|
||||||
font-weight:10;
|
font-weight:10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,3 +44,15 @@ body{
|
||||||
float: none;
|
float: none;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title{
|
||||||
|
font-size:22px;
|
||||||
|
color:#B80000;
|
||||||
|
font: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sentiment-chart{
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 200px;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
var score_timeseries = document.getElementById('timeseries');
|
var score_timeseries = document.getElementById('timeseries');
|
||||||
var mil = d3.format('$.3s')
|
var mil = d3.format('$.3s')
|
||||||
|
var update_freq = 200
|
||||||
|
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
'size': {
|
'size': {
|
||||||
'height': 300
|
'height': 300
|
||||||
|
|
@ -23,8 +26,8 @@ var data = {
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'colors': {
|
'colors': {
|
||||||
'IMDB Score': '#6998A6',
|
'IMDB Score': '#B80000',
|
||||||
'gross': '#966001',
|
'gross': '#fd8d3c',
|
||||||
'x': '#08414C'
|
'x': '#08414C'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -74,8 +77,13 @@ var data = {
|
||||||
$('#year').html(year)
|
$('#year').html(year)
|
||||||
$('#score').html(score)
|
$('#score').html(score)
|
||||||
$('#gross').html(gross)
|
$('#gross').html(gross)
|
||||||
|
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_words_year(year)
|
||||||
t = data
|
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()})
|
$('#genre').change(function(){update_all()})
|
||||||
$('#start_year').change(function(){update_all()})
|
$('#start_year').change(function(){update_all()})
|
||||||
$('#end_year').change(function(){update_all()})
|
$('#end_year').change(function(){update_all()})
|
||||||
|
$('#download').click(function(){download()})
|
||||||
|
|
||||||
jQuery(document).ready(function(){
|
jQuery(document).ready(function(){
|
||||||
jQuery(".chosen").chosen();
|
jQuery(".chosen").chosen();
|
||||||
|
|
@ -117,22 +126,34 @@ jQuery(document).ready(function(){
|
||||||
$('#word_cloud').jQCloud([{'text':'pyDataVizDay', 'weight':1}], word_coud_settings)
|
$('#word_cloud').jQCloud([{'text':'pyDataVizDay', 'weight':1}], word_coud_settings)
|
||||||
update_all()
|
update_all()
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function download(){
|
||||||
|
url = url_params('/api/download?')
|
||||||
|
window.location = url
|
||||||
|
}
|
||||||
function update_all(){
|
function update_all(){
|
||||||
update_words()
|
update_words()
|
||||||
update_ts()
|
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
|
var url = base
|
||||||
if (_top.val().length>0){url = url + 'top=' + _top.val() + '&'}
|
if (_top.val().length>0){url = url + 'top=' + _top.val() + '&'}
|
||||||
if (language.val().length>0){url = url + 'language=' + language.val() + '&'}
|
if (language.val().length>0){url = url + 'language=' + language.val() + '&'}
|
||||||
if (country.val().length>0){url = url + 'country=' + country.val() + '&'}
|
if (country.val().length>0){url = url + 'country=' + country.val() + '&'}
|
||||||
if (genre.val().length>0){url = url + 'genre=' + genre.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 (start_year_val>0){url = url + 'start_year=' + String(start_year_val) + '&'}
|
||||||
if (end_year.val().length>0){url = url + 'end_year=' + end_year.val() + '&'}
|
if (end_year_val>0){url = url + 'end_year=' + String(end_year_val) + '&'}
|
||||||
|
|
||||||
return url
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
<div class="col-sm-1">
|
||||||
</div>
|
<button id='download' class="glyphicon glyphicon-download-alt"></button>
|
||||||
</div>
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
<!-- Load d3.js and c3.js -->
|
<!-- Load d3.js and c3.js -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqcloud/1.0.4/jqcloud.css">
|
<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://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>
|
<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">
|
<link rel="stylesheet" href="static/node_modules/chosen-js/chosen.css">
|
||||||
<script src="static/node_modules/chosen-js/chosen.jquery.js"></script>
|
<script src="static/node_modules/chosen-js/chosen.jquery.js"></script>
|
||||||
|
|
@ -28,11 +28,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='col-sm-1'>
|
<div class='col-sm-1'>
|
||||||
Score: <div class='kpi' id='score'>
|
Score: <div class='kpi' id='score' style='color:#B80000'>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='col-sm-4'>
|
<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>
|
||||||
<div class='col-sm-9'></div>
|
<div class='col-sm-9'></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -45,10 +45,39 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" min-height:150px>
|
<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 id='word_cloud'></div>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
<script src='static/js/enthusiast.js'></script>
|
<script src='static/js/enthusiast.js'></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
<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://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>
|
<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://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>
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
# Open The Viz
|
||||||
|
|
||||||
[pydatavizday.herokuapp.com](pydatavizday.herokuapp.com)
|
[pydatavizday.herokuapp.com](pydatavizday.herokuapp.com)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue