Для новичков, которые пытаются сложить Flask и диаграмму JS вместе, общий подход, по-видимому, заключается в написании кода Jinja, который использует циклы для вывода Javascript или вручную использует выражения Jinja в JS. Это может быстро превратиться в кошмар обслуживания.
Вот мой подход, который позволяет вам определять данные, которые вы хотите отобразить в Python, помещать холст в свой шаблон с минимальными JS, а затем динамически обновлять диаграмму, используя Javascript Fetch API.
Вы можете клонировать репозиторий flask -chart js.
У вас может быть один маршрут, который отображает страницу, содержащую диаграмма:
@app.route('/')
def index():
return render_template('index.html', CHART_ENDPOINT = url_for('data'))
CHART_ENDPOINT
в этом случае будет /data
, что соответствует другому маршруту, который возвращает JSON. У меня также есть вспомогательная функция, которая преобразует времена эпох в формат, совместимый с ISO 8601, который работает с моментом.
import datetime as DT
def conv(epoch):
return DT.datetime.utcfromtimestamp(epoch).isoformat()
@app.route('/data')
def data():
d = {'datasets':
[
{'title': 'From Dict',
'data': [ {'x': conv(1588745371), 'y': 400},
{'x': conv(1588845371), 'y': 500},
{'x': conv(1588946171), 'y': 800} ]
},
]
}
return jsonify(d)
Теперь в шаблоне вы можете разместить элемент холста диаграммы с атрибутом data-endpoint
:
<canvas id="canvas" data-endpoint='{{CHART_ENDPOINT}}'></canvas>
Затем я реализовал две JS функции, которые в том же шаблоне позволяют вам создать диаграмму и загрузить данные из предоставленной конечной точки:
<script type='text/javascript'>
var ctx = document.getElementById('canvas');
myChart = create_chart(ctx);
window.onload = function () {
load_data(myChart)
};
</script>
В create_chart
функция конечная точка получается из атрибута data-endpoint
и добавляется к объекту config
перед назначением на эту диаграмму (кредит) :
config.endpoint = ctx.dataset.endpoint;
return new Chart(ctx.getContext('2d'), config);
Функция load_data
затем обращается к конечной точке из chart.config.endpoint
, что означает, что она всегда получает правильные данные для предоставленной диаграммы.
Вы также можете установить единицы времени при создании диаграммы:
myChart = create_chart(ctx, 'hour') # defaults to 'day'
Я обнаружил, что обычно это нужно настраивать в зависимости от диапазона данных.
Это было бы тривиально изменить код, чтобы получить это таким же образом в качестве конечной точки в функции create_chart
. Что-то вроде config.options.scales.xAxes[0].time.unit = ctx.datasets.unit
, если атрибут был data-unit
. Это также можно сделать для других переменных.
Вы также можете передать строку из внешнего интерфейса при загрузке данных (скажем, dynamicChart
- это еще одна диаграмма, созданная описанным выше методом):
load_data(dynamicChart, 'query_string')
Это сделает 'query_string'
доступным в функции flask как request.args.get('q')
Это полезно, если вы хотите реализовать (например) текстовое поле ввода, которое отправляет строку в бэкэнд, чтобы бэкэнд мог как-то его обработать и вернуть настроенный набор данных, который отображается на диаграмме. Маршрут /dynamic
в репо как бы демонстрирует это.
Вот как это выглядит при рендеринге:
![rendered chart](https://i.stack.imgur.com/c6ABc.png)
Как вы можете увидим, что тогда можно также разместить несколько диаграмм на одной странице.