From c9c3f710ec9a037ef44bd2cc734f1c1bfc548388 Mon Sep 17 00:00:00 2001 From: Ossi Laine <ossi.laine@utu.fi> Date: Mon, 10 Jun 2019 14:40:25 +0300 Subject: [PATCH] Export embody results as bitmap image --- app/routes.py | 51 ++++++++++++++++++++++++++--------------- app/static/js/canvas.js | 25 ++++++++++++-------- app/task/views.py | 25 ++++++++++---------- app/templates/base.html | 3 --- embody_plot.py | 11 +++++---- 5 files changed, 67 insertions(+), 48 deletions(-) diff --git a/app/routes.py b/app/routes.py index 9a58a83..0db3d78 100644 --- a/app/routes.py +++ b/app/routes.py @@ -388,24 +388,39 @@ def download_csv(): for participant in participants: - # append user session id - answer_row += participant.session + ';' - - # TODO: - # append background question answers - bg_answers = background_question_answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() - bg_answers_list = [(a.answer) for a in bg_answers] - answer_row += ';'.join(bg_answers_list) + ';' - - # append slider answers - slider_answers = answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() - answers_list = [ a.answer for a in slider_answers] - answer_row += ';'.join(answers_list) + ';' - - # append embody answers (coordinates) - embody_answers = embody_answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() - answers_list = [ json.dumps(list(zip( json.loads(a.coordinates)['x'], json.loads(a.coordinates)['y']))) for a in embody_answers] - answer_row += ';'.join(answers_list) + try: + + # append user session id + answer_row += participant.session + ';' + + # append background question answers + bg_answers = background_question_answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() + bg_answers_list = [(a.answer) for a in bg_answers] + answer_row += ';'.join(bg_answers_list) + ';' + + # append slider answers + slider_answers = answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() + answers_list = [ a.answer for a in slider_answers] + answer_row += ';'.join(answers_list) + ';' if slider_answers else '' + + # append embody answers (coordinates) + # save embody answers as bitmap images + embody_answers = embody_answer.query.filter_by(answer_set_idanswer_set=participant.idanswer_set).all() + answers_list = [] + for embody_answer_data in embody_answers: + embody_answer_data = json.loads(embody_answer_data.coordinates) + coordinates_to_bitmap = [[0 for x in range(embody_answer_data['height'] + 2)] for y in range(embody_answer_data['width'] + 2)] + for point in list(zip( embody_answer_data['x'], embody_answer_data['y'])): + coordinates_to_bitmap[point[0]][point[1]] += 0.1 + + answers_list.append(json.dumps(coordinates_to_bitmap)) + + # old way to save only visited points: + # answers_list = [ json.dumps(list(zip( json.loads(a.coordinates)['x'], json.loads(a.coordinates)['y']))) for a in embody_answers] + answer_row += ';'.join(answers_list) if embody_answers else '' + + except TypeError as err: + print(err) csv += answer_row + '\r\n' answer_row = '' diff --git a/app/static/js/canvas.js b/app/static/js/canvas.js index c7a1e72..9f30042 100644 --- a/app/static/js/canvas.js +++ b/app/static/js/canvas.js @@ -21,6 +21,8 @@ $(document).ready(function()Â { var clickRadius = new Array(); var clickDrag = new Array(); var paint; + var width = 0; + var height = 0; var drawRadius=13 var default_embody=false var points = [] @@ -49,16 +51,16 @@ $(document).ready(function()Â { newImage = new Image(); newImage.src = img.src - imageId = img.id - var width = newImage.width; - var height = newImage.height; - - context.canvas.height = height - context.canvas.width = width - - context.drawImage(newImage, 0, 0); - $(img).hide() + newImage.onload = function()Â { + imageId = img.id + width = newImage.width; + height = newImage.height; + context.canvas.height = height + context.canvas.width = width + context.drawImage(newImage, 0, 0); + $(img).hide() + } } // Click handlers @@ -140,7 +142,9 @@ $(document).ready(function()Â { id: imageId, x: clickX, y: clickY, - r: clickRadius + r: clickRadius, + width: width, + height: height }) clickX = [] @@ -150,6 +154,7 @@ $(document).ready(function()Â { if ($(img).hasClass('last-embody')) { // Send data to db try { + console.log(points) points = JSON.stringify(points) $("#canvas-data").val(points); $("#canvas-form").submit(); diff --git a/app/task/views.py b/app/task/views.py index c6ae884..9ed7b78 100644 --- a/app/task/views.py +++ b/app/task/views.py @@ -171,21 +171,10 @@ def task_embody(page_num): # Add answer to DB if check_answer is None: for coordinate_data in coordinates: - - idembody = int(coordinate_data['id'].split('-')[1]) - del coordinate_data['id'] - del coordinate_data['r'] - - participant_answer = embody_answer( - answer_set_idanswer_set=session['answer_set'], coordinates=json.dumps(coordinate_data), page_idpage=page_id, embody_question_idembody=idembody) - db.session.add(participant_answer) - db.session.commit() - + save_coordinates(coordinate_data, page_id) else: flash("Page has been answered already. Answers discarded") - - # Check if there are unanswered slider questions -> if true redirect to same page if slider_on(): update_answer_set_type('slider') @@ -195,6 +184,18 @@ def task_embody(page_num): return next_page(pages) +def save_coordinates(coordinate_data, page_id): + """All of the embody results from one page/stimulant is saved in this method""" + idembody = int(coordinate_data['id'].split('-')[1]) + del coordinate_data['id'] + del coordinate_data['r'] + + participant_answer = embody_answer( + answer_set_idanswer_set=session['answer_set'], coordinates=json.dumps(coordinate_data), page_idpage=page_id, embody_question_idembody=idembody) + db.session.add(participant_answer) + db.session.commit() + + @task_blueprint.route('/question/<int:page_num>', methods=['POST']) def task_answer(page_num): '''Save slider answers to database''' diff --git a/app/templates/base.html b/app/templates/base.html index 8b35de2..f94a356 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -15,11 +15,8 @@ <script src="{{ url_for('static', filename='lib/js/bootstrap.min.js') }}" ></script> <title>Onni</title> - <!-- Bootstrap core CSS --> - <link href="/lib/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> - <link href="/static/css/slider.css" rel="stylesheet"> </head> diff --git a/embody_plot.py b/embody_plot.py index d8c8634..ea1af5d 100644 --- a/embody_plot.py +++ b/embody_plot.py @@ -182,14 +182,10 @@ def plot_coordinates(coordinates, image_path=DEFAULT_IMAGE_PATH): # Init plots fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2) - # Plot coordinates as points - ax1.set_title("raw points") - ax1.plot(coordinates["x"],coordinates["y"], 'ro', alpha=0.2) - ax1.imshow(image) # Draw circles from coordinates (imshow don't need interpolation) # TODO: set sigma according to brush size! - ax2.set_title("gaussian disk around points") + ax2.set_title("gaussian disk around points / raw image") # set height/width from image frame = np.zeros((image_data[0] + 10,image_data[1] + 10)) @@ -215,6 +211,11 @@ def plot_coordinates(coordinates, image_path=DEFAULT_IMAGE_PATH): # with pre-created image mask (IMAGE_PATH_MASK) ax2.imshow(image) + # Plot coordinates as points + ax1.set_title("raw points") + ax1.plot(coordinates["x"],coordinates["y"], 'ro', alpha=0.2) + ax1.imshow(image, alpha=0.6) + # return figure for saving/etc... return fig -- GitLab