Skip to content

Commit

Permalink
Sparklines!
Browse files Browse the repository at this point in the history
  • Loading branch information
ctbarna committed Aug 11, 2011
1 parent a405c51 commit 6014277
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 21 deletions.
12 changes: 6 additions & 6 deletions dashboard/static/js/sparkline.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@
var w = 200,
h = 50;

var data = [3,6,2,7,5,2,1,3,8,9,21,5,7,8,13,14,15,16,17,18,19,20];
var x = d3.scale.linear().domain([0, data.length - 1]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(data)]).range([h, 0]);
var max = d3.max(data);
var min = d3.min(data);
var sparkData = [3,6,2,7,5,2,1,3,8,9,21,5,7,8,13,14,15,16,17,18,19,20];
var x = d3.scale.linear().domain([0, sparkData.length - 1]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(sparkData)]).range([h, 0]);
var max = d3.max(sparkData);
var min = d3.min(sparkData);

var vis = d3.select("body")
.append("svg:svg")
Expand All @@ -91,7 +91,7 @@
var initial_path = vis.append("svg:path").attr("d", line(data)).attr("stroke-linecap","round");

var initial_circles = vis.selectAll("circle.area")
.data(data)
.data(sparkData)
.enter().append("svg:circle")
.attr("class", function(d,i) {if (d === max) { return 'point max'; } else if (d === min) { return 'point min' } else { return 'point'}})
.attr("cx", function(d,i) { return x(i); })
Expand Down
77 changes: 73 additions & 4 deletions dashboard/templates/geo_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

{% block content %}
<link rel="stylesheet" href="{{ STATIC_URL }}css/street_view_styles.css">
<style>
#spark-line path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}

.line, circle.area {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}

circle.area {
fill: #fff;
}

.point {
fill: #C80000;
stroke: #FFFFFF;
stroke-width: 0px;
}
</style>
<div class="container_12" id="street-content">
<div class="grid_8">
<div id="map">
Expand All @@ -24,7 +47,7 @@ <h1>Open Requests</h1>
</div>
</div>
<div class="grid_4">
<div id="street-stats">
<div id="street-stats" style="">
<h1>{{ title|title }}</h1>
<div id="spark-line"></div>
<p class="caption">30-Day Trend</p>
Expand All @@ -34,10 +57,10 @@ <h1>{{ title|title }}</h1>


<h1>Top Requests</h1>
<table id="top-requests">
<table id="top-requests" style="table-layout:fixed;">
{% for type in stats.request_types %}
<tr>
<td>{{ type.service_name }}</td>
<td style="overflow:hidden;white-space:nowrap;width:75%;">{{ type.service_name }}</td>
<td>{{ type.count }}</td>
</tr>
{% endfor %}
Expand All @@ -46,10 +69,20 @@ <h1>Top Requests</h1>
</div>

<div id="nearby">
<h2>Streets Nearby</h2>
<h2>Nearby</h2>
<table>
{% for nearby_place in nearby %}
<tr>
<td><a href="{{ nearby_place.get_absolute_url }}">{{ nearby_place.name }}</a></td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
<script>
var sparkData = [10,5,11];
</script>
{% endblock %}

{% block custom_scripts %}
Expand Down Expand Up @@ -79,5 +112,41 @@ <h2>Streets Nearby</h2>

map.add(po.compass()
.pan("none"));

var w = 200,
h = 50;

var sparkData = {{ stats.opened_by_day }};
var x = d3.scale.linear().domain([0, sparkData.length - 1]).range([0, w]);
var y = d3.scale.linear().domain([0, d3.max(sparkData)]).range([h, 0]);
var max = d3.max(sparkData);
var min = d3.min(sparkData);

var vis = d3.select("#spark-line")
.append("svg:svg")
.attr("width", w + 40)
.attr("height", h + 40)
.append("svg:g")
.attr("transform", "translate(" + 20 + ", " + 20 + ")");

var new_circles = vis.selectAll("circle.area")
.data(sparkData)
.enter().append("svg:circle");

var line = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d) { return y(d); })
.interpolate("cardinal")

//appending the line
var initial_path = vis.append("svg:path").attr("d", line(sparkData)).attr("stroke-linecap","round");

var initial_circles = vis.selectAll("circle.area")
.data(sparkData)
.enter().append("svg:circle")
.attr("class", function(d,i) {if (d === max) { return 'point max'; } else if (d === min) { return 'point min' } else { return 'point'}})
.attr("cx", function(d,i) { return x(i); })
.attr("cy", function(d,i) { return y(d); })
.attr("r", function(d) { if (d === max || d === min) { return 3.5 } else { return 0}});
</script>
{% endblock %}
3 changes: 1 addition & 2 deletions dashboard/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@

<div class="grid_4 block {% if delta.time < 0 %}green{% else %}red{% endif %}" id="open-time">
<div class="main">
<div class="number">{{ this_week_stats.average_response }} day
{{ this_week_stats.average_response|pluralize }}</div>
<div class="number">{{ this_week_stats.average_response }} day{{ this_week_stats.average_response|pluralize }}</div>
average response time.
</div>
<span class="delta">{{ delta.time }}</span>% change in response time from last week to this.
Expand Down
10 changes: 10 additions & 0 deletions dashboard/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import datetime

import qsstats
from django.contrib.gis.db.models.fields import GeometryField
from django.utils import simplejson
from django.http import HttpResponse
Expand Down Expand Up @@ -38,6 +40,14 @@ def run_stats(request_obj, **kwargs):
stats['open_requests'] = request_obj.filter(status="Open") \
.order_by('-requested_datetime')[:10]

# Opened requests by day (limit: 30)
time_delta = datetime.timedelta(days=30)
latest = request_obj.latest('requested_datetime')
qss = qsstats.QuerySetStats(request_obj, 'requested_datetime')
time_series = qss.time_series(latest.requested_datetime - time_delta,
latest.requested_datetime)
stats['opened_by_day'] = [t[1] for t in time_series]

return stats

def calculate_delta(new, old):
Expand Down
15 changes: 6 additions & 9 deletions dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def index(request, geography=None, is_json=False):
if is_json is False:
neighborhoods = Geography.objects.all()
c_dict['neighborhoods'] = neighborhoods
c_dict['latest'] = most_recent.requested_datetime,
c_dict['latest'] = most_recent.requested_datetime
c = Context(c_dict)
return render(request, 'index.html', c)
else:
Expand All @@ -86,17 +86,13 @@ def neighborhood_list(request):

def neighborhood_detail(request, neighborhood_id):
neighborhood = Geography.objects.get(pk=neighborhood_id)
nearby = Geography.objects.all().distance(neighborhood.geo) \
.exclude(name=neighborhood.name).order_by('distance')[:5]

# Get the requests inside the neighborhood, run the stats
requests = Request.objects.filter(geo_point__contained=neighborhood.geo)
stats = run_stats(requests)

# c = Context({
# 'neighborhood': neighborhood,
# 'stats': stats
# })
# return render(request, 'neighborhood_detail.html', c)


title = neighborhood.name

neighborhood.geo.transform(4326)
Expand All @@ -107,7 +103,8 @@ def neighborhood_detail(request, neighborhood_id):
'title': title,
'geometry': simple_shape.geojson,
'centroid': simple_shape.centroid.geojson,
'stats': stats
'stats': stats,
'nearby': nearby
})

return render(request, 'geo_detail.html', c)
Expand Down

0 comments on commit 6014277

Please sign in to comment.