Trong dự án này, tôi đang thử nghiệm gửi dữ liệu giữa Javascript và Python bằng khung web Flask. Ngoài ra, tôi sẽ sử dụng matplotlib để tạo biểu đồ động dựa trên dữ liệu đầu vào do người dùng cung cấp
Điểm học tập chính
- Gửi dữ liệu từ Python sang Javascript
- Nhận dữ liệu bằng Python từ Javascript
- Tạo hình ảnh động bằng cách sử dụng tuyến đường Flask đặc biệt
Bit quan trọng
Gửi
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...0 từ Javascript tới Python bằng lệnh gọi POST tới postmethod và sử dụng biến biểu mẫu canvas_data. Cuộc gọi POST đưa ra phản hồi từ Python và trang được chuyển hướng đến trang kết quả với ID duy nhất đã cho
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...
Truy xuất
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...1 từ yêu cầu POST và ghi nội dung vào một tệp. Trả lại id duy nhất được sử dụng để ghi vào tệp
... @app.route['/postmethod', methods=['POST']] def post_javascript_data[]: jsdata = request.form['canvas_data'] unique_id = create_csv[jsdata] params = {'unique_id': unique_id } return jsonify[params] ...
Thực hiện
Cốt lõi của ứng dụng web nằm trong tệp này. Ở đây tôi xác định các tuyến khác nhau cho trang web và chỉ định cài đặt. Lộ trình mặc định hiển thị chỉ mục. html nơi canvas được hiển thị. Lộ trình kết quả sẽ hiển thị hình ảnh sau khi hình ảnh được vẽ, dựa trên ID duy nhất được cung cấp. Lộ trình postmethod được xác định để xử lý dữ liệu đến từ Javascript vào Python thông qua lệnh gọi POST. Nội dung của biến POST được ghi vào tệp CSV có thể được sử dụng lại trên trang kết quả nơi dữ liệu được tải từ cùng một tệp này
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...2
from __future__ import print_function from flask import Flask, render_template, make_response from flask import redirect, request, jsonify, url_for import io import os import uuid from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure import numpy as np app = Flask[__name__] app.secret_key = 's3cr3t' app.debug = True app._static_folder = os.path.abspath["templates/static/"] @app.route['/', methods=['GET']] def index[]: title = 'Create the input' return render_template['layouts/index.html', title=title] @app.route['/results/', methods=['GET']] def results[unique_id]: title = 'Result' data = get_file_content[unique_id] return render_template['layouts/results.html', title=title, data=data] @app.route['/postmethod', methods = ['POST']] def post_javascript_data[]: jsdata = request.form['canvas_data'] unique_id = create_csv[jsdata] params = { 'unique_id' : unique_id } return jsonify[params] @app.route['/plot/'] def plot[imgdata]: data = [float[i] for i in imgdata.strip['[]'].split[',']] data = np.reshape[data, [200, 200]] fig = Figure[] axis = fig.add_subplot[1, 1, 1] axis.axis['off'] axis.imshow[data, interpolation='nearest'] canvas = FigureCanvas[fig] output = io.BytesIO[] canvas.print_png[output] response = make_response[output.getvalue[]] response.mimetype = 'image/png' return response def create_csv[text]: unique_id = str[uuid.uuid4[]] with open['images/'+unique_id+'.csv', 'a'] as file: file.write[text[1:-1]+"\n"] return unique_id def get_file_content[unique_id]: with open['images/'+unique_id+'.csv', 'r'] as file: return file.read[] if __name__ == '__main__': app.run[host='0.0.0.0', port=5000]
Phần thứ hai của phép thuật xảy ra trong tệp Javascript. Trong tệp này, canvas được tạo và thêm vào DOM. Chuột được sử dụng để vẽ các chấm trên canvas với màu sắc và bán kính được xác định trước. Một nút được sử dụng để gửi dữ liệu của bản vẽ hiện tại trên canvas và một nút khác được sử dụng để xóa canvas
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...3
$[ document ].ready[function[] { function createCanvas[parent, width, height] { var canvas = document.getElementById["inputCanvas"]; canvas.context = canvas.getContext['2d']; return canvas; } function init[container, width, height, fillColor] { var canvas = createCanvas[container, width, height]; var ctx = canvas.context; ctx.fillCircle = function[x, y, radius, fillColor] { this.fillStyle = fillColor; this.beginPath[]; this.moveTo[x, y]; this.arc[x, y, radius, 0, Math.PI * 2, false]; this.fill[]; }; ctx.clearTo = function[fillColor] { ctx.fillStyle = fillColor; ctx.fillRect[0, 0, width, height]; }; ctx.clearTo["#fff"]; canvas.onmousemove = function[e] { if [!canvas.isDrawing] { return; } var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; var radius = 10; var fillColor = 'rgb[102,153,255]'; ctx.fillCircle[x, y, radius, fillColor]; }; canvas.onmousedown = function[e] { canvas.isDrawing = true; }; canvas.onmouseup = function[e] { canvas.isDrawing = false; }; } var container = document.getElementById['canvas']; init[container, 200, 200, '#ddd']; function clearCanvas[] { var canvas = document.getElementById["inputCanvas"]; var ctx = canvas.getContext["2d"]; ctx.clearRect[0, 0, canvas.width, canvas.height]; } function getData[] { var canvas = document.getElementById["inputCanvas"]; var imageData = canvas.context.getImageData[0, 0, canvas.width, canvas.height]; var data = imageData.data; var outputData = [] for[var i = 0; i {% block title %}{% endblock %} - Simple Flask app {% endblock %} Home Results {% block content %}{% endblock %} {% block footer %} © Copyright 2017 by Jitse-Jan. {% endblock %}
Mã cho chỉ mục. html và kết quả. html có thể được giữ ở mức tối thiểu theo cách này
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...5
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...1
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...6
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...3
Quan trọng. Xin lưu ý rằng đối với nguồn của hình ảnh, URL cụ thể cho hình ảnh matplotlib được sử dụng. Lộ trình cho cốt truyện được gọi với tham số
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...7 chứa dữ liệu
Tôi đã giữ bản định kiểu rất cơ bản vì dự án này không nhằm mục đích tạo giao diện bóng bẩy nhất
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...8
... $.post[ "/postmethod", { canvas_data: JSON.stringify[outputData] }, function[err, req, resp]{ window.location.href = "/results/"+resp["responseJSON"]["unique_id"]; }]; ...6
Sau khi đặt tất cả các tệp lại với nhau, ứng dụng có thể được khởi động và truy cập trên cổng 5000 trên máy chủ cục bộ