我只是想知道使用Django为网站创建交互式绘图的最佳方法是什么。当用户更改方程参数时,绘图需要以交互方式更改。任何推荐的套餐?
答案 0 :(得分:0)
我会使用Highcharts,然后您需要创建django后端才能将数据存储到数据库或其他内容中......
以下是我为学校所做的事情的一个例子:
glucose.html
:
{% extends "base.html" %}
{% block title %}Blood Glucose{% endblock %}
{% block appmedia %}{{glucose_form.media}}{% endblock %}
{% block sidebar %}
<li data-toggle="collapse" data-target="#reading" class="collapsed">
<a href="#">Add New Reading</a>
</li>
<ul class="sub-menu collapse" id="reading">
<form id="glucose_form" action="/glucose/submit" method="POST">
{% csrf_token %}
{{ glucose_form.as_p }}
</form>
<button type="submit" id="glucose_submit">Submit</button>
</ul>
<li data-toggle="collapse" data-target="#settings" class="collapsed">
<a href="#">Update Alert Settings</a>
</li>
<ul class="sub-menu collapse" id="settings">
<form id="glucose_boundary_form" action="/glucose/goals" method="POST">
{% csrf_token %}
{{ glucose_boundary_form.as_p }}
</form>
<button type="submit" id="glucose_goals">Submit</button>
</ul>
{% endblock %}
{% block content %}
{{ glucose_result }}
<div id="glucose_chart" style="width:100%; height:75%;"></div>
<script type="text/javascript" >
var chart = $('#glucose_chart').highcharts({
chart: {
type: 'line'
},
title: {
text: 'Blood Glucose'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: {
minute: '%l:%M %p',
hour: '%l %p',
day: '%b %d<br>%Y',
week: '%b %d<br>%Y',
month: '%b %Y',
year: '%Y'
},
title:{
text: null
},
},
yAxis: {
type: 'integer',
title:{
text: null
},
min: 0,
max: {{ glucose_boundary.upper_bound }} * 1.5,
ceiling: {{ glucose_boundary.upper_bound }} * 1.5,
gridLineWidth: 0,
plotBands: [{
id: 'upper_bound',
color: 'red',
from: '{{ glucose_boundary.upper_bound }}',
to: {{ glucose_boundary.upper_bound }} * 1.5,
},
{
id: 'lower_bound',
color: 'red',
from: '{{ glucose_boundary.lower_bound }}',
to: 0,
}],
plotLines: [{
id: 'goal_line',
color: 'lime',
value: '{{ glucose_boundary.glucose_goal }}',
width: 2
}]
},
plotOptions: {
series: {
states: {
hover: {
enabled: false
}
}
},
spline: {
marker: {
enabled: true
}
}
},
series: [{
color: 'blue',
showInLegend: false,
data: [
{% for result in glucose_results %}
{
'name': 'Result',
'x': Date.UTC(
{{result.date_time.year}},
({{result.date_time.month}} - 1),
{{result.date_time.day}},
{{result.date_time.hour}},
{{result.date_time.minute}}
),
'y': {{result.glucose}},
},
{% endfor %}
]
}],
tooltip: {
formatter: function() {
foods = this.point.name.replace(new RegExp('<br>', 'g'), '<br>');
timestamp = new Date(this.point.x).toLocaleFormat('%b %d, %Y');
return '<b><i>' + timestamp + ': ' + this.point.y + ' Calories</i></b><br><br>' + foods;
}
},
credits: {
enabled: false
}
});
$('button#glucose_submit').click(function() {
$.ajax({
url:'glucose/submit',
type: 'POST',
data: $('form#glucose_form').serialize(),
success: function(data) {
document.getElementById("glucose_form").reset();
}
});
});
$('button#glucose_goals').click(function() {
$.ajax({
url:'glucose/goals',
type: 'POST',
data: $('form#glucose_boundary_form').serialize(),
success: function(data) {
var chart = $('#glucose_chart').highcharts();
chart.yAxis[0].removePlotBand('upper_bound')
chart.yAxis[0].addPlotBand({
id: 'upper_bound',
color: 'red',
from: document.getElementById('id_upper_bound').value,
to: document.getElementById('id_upper_bound').value * 1.5,
});
chart.yAxis[0].removePlotBand('lower_bound')
chart.yAxis[0].addPlotBand({
id: 'lower_bound',
color: 'red',
from: document.getElementById('id_lower_bound').value,
to: 0,
});
chart.yAxis[0].removePlotLine('goal_line')
chart.yAxis[0].addPlotLine({
id: 'goal_line',
color: 'lime',
value: document.getElementById('id_glucose_goal').value,
width: 2
});
chart.redraw();
}
});
});
// ajax components
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
</script>
<style>
#sidebar {background-color: d46a6a; width: 18%; border-radius: 10px; margin: 10px}
a{color: #ffffff !important}
.container-fluid {background-color: d46a6a !important; border-color: d46a6a !important}
label{color: #ffffff}
body{background-color: #aa3939}
.navbar-header {background-color: d46a6a!important, border-color:d46a6a !important}
#content{background-color: white; border-radius: 10px}
</style>
{% endblock %}
这是我的views.py
:
from bgpal.models import *
from bgpal.forms import *
from datetime import datetime
from django.db import transaction
from django.shortcuts import render
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
# Create your views here.
def home(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('loginregistration.views.login'))
return HttpResponseRedirect('glucose')
@login_required
def glucose(request):
if request.method == 'GET':
glucose_boundary = __get_glucose_boundary_or_create_initial(request)
glucose_results = __get_glucose_points(request)
glucose_boundary_data = {'upper_bound':glucose_boundary.upper_bound,
'lower_bound':glucose_boundary.lower_bound,
'glucose_goal':glucose_boundary.glucose_goal}
glucose_boundary_form = BloodGlucoseBoundForm(initial=glucose_boundary_data)
glucose_form = BloodGlucoseForm()
payload = {'glucose_boundary':glucose_boundary, 'glucose_results':glucose_results,
'glucose_boundary_form':glucose_boundary_form, 'glucose_form':glucose_form}
return render(request, 'glucose.html', payload)
@login_required
def glucose_submit_result(request):
if request.method == 'POST':
with transaction.atomic():
try:
glucose = request.POST['glucose']
insulin_dosage = request.POST['insulin_dosage']
date_time = __get_datetime(request, 'date_time')
glucose_result = BloodGlucoseModel(user=request.user, glucose=glucose,
insulin_dosage=insulin_dosage, date_time=date_time)
glucose_result.save()
return HttpResponse("Success")
except:
return HttpResponse("Failed")
return HttpResponse("Failed")
@login_required
def glucose_update_result(request):
if request.method == 'POST':
with transaction.atomic():
try:
glucose_result = get_object_or_404(BloodGlucoseModel, user=request.user, id=request.POST['id'])
glucose_result.glucose = request.POST['glucose']
glucose_result.insulin_dosage = request.POST['insulin_dosage']
glucose_result.date_time = request.POST['date_time']
glucose_result.save()
return HttpResponse("Success")
except:
return HttpResponse("Failed")
return HttpResponse("Failed")
@login_required
def glucose_remove_result(request):
if request.method == 'POST':
with transaction.atomic():
try:
glucose_result = get_object_or_404(BloodGlucoseModel, user=request.user, id=request.POST['id'])
glucose_result.delete()
return HttpResponse("Success")
except:
return HttpResponse("Failed")
return HttpResponse("Failed")
@login_required
def glucose_update_goals(request):
if request.method == 'POST':
with transaction.atomic():
try:
glucose_boundary = __get_glucose_boundary_or_create_initial(request)
glucose_boundary.upper_bound = request.POST['upper_bound']
glucose_boundary.lower_bound = request.POST['lower_bound']
glucose_boundary.glucose_goal = request.POST['glucose_goal']
glucose_boundary.save()
return HttpResponse("Success")
except:
return HttpResponse("Failed")
return HttpResponse("Failed")
def __get_glucose_boundary_or_create_initial(request):
glucose_boundary = BloodGlucoseBoundModel.objects.filter(user=request.user)
if glucose_boundary:
glucose_boundary = glucose_boundary[0]
else:
glucose_boundary = BloodGlucoseBoundModel(user=request.user, upper_bound=200,
lower_bound=50, glucose_goal=100)
glucose_boundary.save()
return glucose_boundary
def __get_glucose_points(request):
glucose_list =BloodGlucoseModel.objects.filter(user=request.user)
glucose_list = glucose_list.order_by('date_time')
glucose_points = []
for sugar in glucose_list:
date_time = datetime(sugar.date_time.year, sugar.date_time.month, sugar.date_time.day,sugar.date_time.hour,sugar.date_time.minute, sugar.date_time.second)
glucose_points.append({'glucose': sugar.glucose, 'date_time': date_time})
return glucose_points
def __get_datetime(request, field_name):
# Look here for datetime string format http://www.tutorialspoint.com/python/time_strptime.htm
return datetime.strptime(request.POST[field_name], '%m/%d/%Y %I:%M %p')