Changeset 298


Ignore:
Timestamp:
Apr 7, 2011, 5:59:15 PM (14 years ago)
Author:
Rick van der Zwet
Message:
  • Move javascript magic into seperate functions for readability.
  • Implemented form allowing user to alter his data.
Location:
django_apps/running
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • django_apps/running/templates/user_index.html

    r291 r298  
    55  <head>
    66     <script type="text/javascript" src="{{ STATIC_PREFIX }}protovis-r3.2.js"></script>
     7     <script type="text/javascript" src="{{ STATIC_PREFIX }}week-total.js"></script>
     8     <script type="text/javascript" src="{{ STATIC_PREFIX }}year-total.js"></script>
    79     <style type="text/css">
    810       #fig2 {
     
    2123    <h1>Welcome {{ user }}</h1>
    2224    <div id="center">
    23       <h3>Week averages</h3>
     25      <h3>Week totals</h3>
    2426      <div id="fig2">
    2527        <div id="week-statistics"> </div>
     
    3436      </div>
    3537    </div>
     38    <form method="post" action="">
     39    {% csrf_token %}
     40    {{ formset.management_form }}
     41    <table>
     42    {% for form in formset %}
     43      {% if forloop.first %}
     44        <tr>
     45        {% for field in form.visible_fields %}
     46          <th>{{ field.label_tag }}</th>
     47        {% endfor %}
     48        </tr>
     49      {% endif %}
     50      <tr>
     51      {% for field in form.visible_fields %}
     52        {% if forloop.first %}
     53          {% for hidden in form.hidden_fields %}
     54            {{ hidden }}
     55          {% endfor %}
     56        {% endif %}
     57
     58       <td>{{ field.errors }}{{ field }}</td>
     59      {% endfor %}
     60      </tr>
     61    {% endfor %}
     62    </table>
     63    <input type="submit" value="Submit Values"/>
     64    </form>
    3665    Beheer al je gegevens <a href="{% url admin:running_user_change user.id %}">hier</a>.
    3766
     67
    3868<script type="text/javascript+protovis">
    39 
    40 // Get the required data
    41 var xhr = new XMLHttpRequest();
    42 xhr.open('GET', '{% url running.views.json_user_column user.id %}', false);
    43 xhr.send(null);
    44 var myData = JSON.parse(xhr.responseText, function (key, value) {
    45     return value;
    46 });
    47 
    48 Array.prototype.max = function () {
    49     return Math.max.apply(Math, this);
    50     };
    51 
    52 data = myData.data;
    53 itemCount = data.length;
    54 var  w = 1000,
    55     h = 100,
    56     x = pv.Scale.ordinal(pv.range(itemCount)).splitBanded(0, w, 4/5),
    57     y = pv.Scale.linear(0, myData.data.max()).range(0, h);
    58 
    59 var vis = new pv.Panel().canvas('week-statistics')
    60     .width(w)
    61     .height(h)
    62     .bottom(20)
    63     .left(20)
    64     .right(5)
    65     .top(5);
    66 
    67 var bar = vis.add(pv.Bar)
    68     .data(data)
    69     .left(function() x(this.index))
    70     .width(x.range().band)
    71     .bottom(0)
    72     .height(y);
    73 
    74 bar.anchor("top").add(pv.Label)
    75     .textStyle("white")
    76     .text(function(d) d.toFixed(1));
    77 
    78 bar.anchor("bottom").add(pv.Label)
    79     .textMargin(5)
    80     .textBaseline("top")
    81     .text(function() myData.label[this.index]);
    82 
    83 vis.add(pv.Rule)
    84     .data(y.ticks())
    85     .bottom(function(d) Math.round(y(d)) - .5)
    86     .strokeStyle(function(d) d ? "rgba(255,255,255,.3)" : "#000")
    87     .add(pv.Rule)
    88     .left(0)
    89     .width(5)
    90     .strokeStyle("#000")
    91     .anchor("left").add(pv.Label)
    92 
    93 vis.render();
    94 
     69  // Graph Week totals
     70  var xhr = new XMLHttpRequest();
     71  xhr.open('GET', '{% url running.views.json_user_column user.id %}', false);
     72  xhr.send(null);
     73  var myData = JSON.parse(xhr.responseText, function (key, value) {
     74      return value;
     75  });
     76  weekTotalGraph(myData, 'week-statistics');
    9577</script>
    9678
    9779
    9880<script type="text/javascript+protovis">
    99 // Get the required data
    100 var xhr = new XMLHttpRequest();
    101 xhr.open('GET', '{% url running.views.json_user_total user.id %}', false);
    102 xhr.send(null);
    103 
    104 var data = JSON.parse(xhr.responseText, function (key, value) {
    105     var type;
    106     if ( value != null) {
    107       if ( key === 'x') {
    108          return new Date(value);
     81  // Graph Year totals
     82  var xhr = new XMLHttpRequest();
     83  xhr.open('GET', '{% url running.views.json_user_total user.id %}', false);
     84  xhr.send(null);
     85 
     86  var data = JSON.parse(xhr.responseText, function (key, value) {
     87      var type;
     88      if ( value != null) {
     89        if ( key === 'x') {
     90           return new Date(value);
     91        }
    10992      }
    110     }
    111     return value;
    112 });
    113 
    114 var start = data[0].x;
    115 var end = data[data.length - 1].x;
    116 
    117 /* Scales and sizing. */
    118 var w = 810,
    119     h1 = 300,
    120     h2 = 30,
    121     x = pv.Scale.linear(start, end).range(0, w),
    122     y = pv.Scale.linear(0, pv.max(data, function(d) d.y)).range(0, h2);
    123 
    124 /* Interaction state. Focus scales will have domain set on-render. */
    125 var i = {x:200, dx:100},
    126     fx = pv.Scale.linear().range(0, w),
    127     fy = pv.Scale.linear().range(0, h1);
    128 
    129 /* Root panel. */
    130 var vis = new pv.Panel().canvas('total-statistics')
    131     .width(w)
    132     .height(h1 + 20 + h2)
    133     .bottom(20)
    134     .left(30)
    135     .right(20)
    136     .top(5);
    137 
    138 /* Focus panel (zoomed in). */
    139 var focus = vis.add(pv.Panel)
    140     .def("init", function() {
    141         var d1 = x.invert(i.x),
    142             d2 = x.invert(i.x + i.dx),
    143             dd = data.slice(
    144                 Math.max(0, pv.search.index(data, d1, function(d) d.x) - 1),
    145                 pv.search.index(data, d2, function(d) d.x) + 1);
    146         fx.domain(d1, d2);
    147         fy.domain(scale.checked ? [0, pv.max(dd, function(d) d.y)] : y.domain());
    148         return dd;
    149       })
    150     .top(0)
    151     .height(h1);
    152 
    153 /* X-axis ticks. */
    154 focus.add(pv.Rule)
    155     .data(function() fx.ticks())
    156     .left(fx)
    157     .strokeStyle("#eee")
    158   .anchor("bottom").add(pv.Label)
    159     .text(fx.tickFormat);
    160 
    161 /* Y-axis ticks. */
    162 focus.add(pv.Rule)
    163     .data(function() fy.ticks(7))
    164     .bottom(fy)
    165     .strokeStyle(function(d) d ? "#aaa" : "#000")
    166   .anchor("left").add(pv.Label)
    167     .text(fy.tickFormat);
    168 
    169 /* Focus area chart. */
    170 focus.add(pv.Panel)
    171     .overflow("hidden")
    172   .add(pv.Area)
    173     .data(function() focus.init())
    174     .left(function(d) fx(d.x))
    175     .bottom(1)
    176     .height(function(d) fy(d.y))
    177     .fillStyle("lightsteelblue")
    178   .anchor("top").add(pv.Line)
    179     .fillStyle(null)
    180     .strokeStyle("steelblue")
    181     .lineWidth(2);
    182 
    183 /* Context panel (zoomed out). */
    184 var context = vis.add(pv.Panel)
    185     .bottom(0)
    186     .height(h2);
    187 
    188 /* X-axis ticks. */
    189 context.add(pv.Rule)
    190     .data(x.ticks())
    191     .left(x)
    192     .strokeStyle("#eee")
    193   .anchor("bottom").add(pv.Label)
    194     .text(x.tickFormat);
    195 
    196 /* Y-axis ticks. */
    197 context.add(pv.Rule)
    198     .bottom(0);
    199 
    200 /* Context area chart. */
    201 context.add(pv.Area)
    202     .data(data)
    203     .left(function(d) x(d.x))
    204     .bottom(1)
    205     .height(function(d) y(d.y))
    206     .fillStyle("lightsteelblue")
    207   .anchor("top").add(pv.Line)
    208     .strokeStyle("steelblue")
    209     .lineWidth(2);
    210 
    211 /* The selectable, draggable focus region. */
    212 context.add(pv.Panel)
    213     .data([i])
    214     .cursor("crosshair")
    215     .events("all")
    216     .event("mousedown", pv.Behavior.select())
    217     .event("select", focus)
    218   .add(pv.Bar)
    219     .left(function(d) d.x)
    220     .width(function(d) d.dx)
    221     .fillStyle("rgba(255, 128, 128, .4)")
    222     .cursor("move")
    223     .event("mousedown", pv.Behavior.drag())
    224     .event("drag", focus);
    225 
    226  vis.render();
    227 
    228     </script>
     93      return value;
     94  });
     95  yearTotalGraph(data, 'total-statistics');
     96</script>
    22997  </body>
    23098</html>
  • django_apps/running/views.py

    r291 r298  
    33from django.core import serializers
    44from django.http import HttpResponse
     5from django.forms.models import modelformset_factory, inlineformset_factory
     6from django.template import RequestContext
     7
    58from django.shortcuts import render_to_response, get_object_or_404
    69from running.models import Result, User
     
    912def user_index(request, user_name):
    1013    user = get_object_or_404(User, name=user_name)
    11     return render_to_response('user_index.html', { 'user' : user })
     14    ResultFormSet = modelformset_factory(Result, fields=('date', 'distance', 'time'), exclude=('user'), extra=3, can_delete=True)
     15    if request.method == 'POST':
     16       formset = ResultFormSet(request.POST, request.FILES)
     17       if formset.is_valid():
     18         instances = formset.save(commit=False)
     19         for instance in instances:
     20           instance.user = user
     21           instance.save()
     22
     23    result_list = Result.objects.filter(user=user)
     24    formset = ResultFormSet(queryset=result_list)
     25    return render_to_response('user_index.html', { 'user' : user, 'formset' : formset }, context_instance=RequestContext(request))
    1226
    1327def index(request):
     
    3852    result_list = Result.objects.values_list('date', 'distance')
    3953    json_list = []
     54    distance_total = 0.0
    4055    # Output date object in epoch milliseconds as JavaScript find this easy to use.
    4156    for (date,distance) in result_list:
    42         json_list.append({'x': int(date.strftime("%s")) * 1000, 'y' : float(distance)})
     57        distance_total += float(distance)
     58        json_list.append({'x': int(date.strftime("%s")) * 1000, 'y' : distance_total})
    4359    data = json.dumps(json_list, ensure_ascii=False, indent=2)
    4460    return HttpResponse(data,mimetype="application/json")
Note: See TracChangeset for help on using the changeset viewer.