2016-02-11 2 views
-1

Мне просто интересно, что лучший способ создать интерактивные сюжеты для веб-сайта с помощью Django. Когда пользователь меняет параметры уравнения, график должен меняться в интерактивном режиме. Любые рекомендуемые пакеты?Django интерактивные веб-графики

ответ

0

Я хотел бы использовать Highcharts, а затем вам нужно создать Джанго движки для того, чтобы сохранить ваши данные в базу данных или что-то ...

Вот пример того, что я сделал с ним школа:

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('&lt;br&gt;', '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') 
Смежные вопросы