Permalink
Browse files

sliders, combined dates, sparklines

  • Loading branch information...
Charles DeTar
Charles DeTar committed Sep 9, 2010
1 parent e158b3f commit 3e1599caa2d6cbd2bcfe7b0d14cbbd82109f9c5b
@@ -73,6 +73,12 @@ def handle(self, *args, **kwargs):
for i in range(13, 22):
row[i] = int(row[i] or 0)
kwargs = dict(zip(fields, row))
+ try:
+ DiaryEntry.objects.get(report_key=kwargs['report_key'])
+ continue
+ except DiaryEntry.DoesNotExist:
+ pass
+
kwargs['summary'] = clean_summary(kwargs['summary'])
kwargs['latitude'] = float(kwargs['latitude']) if kwargs['latitude'] else None
kwargs['longitude'] = float(kwargs['longitude']) if kwargs['longitude'] else None
@@ -4,9 +4,23 @@
<div class='sidebar'>
{% include "afg/_logo.html" %}
- <form method='get' action='{% url afg.search %}'>
+ <script type='text/javascript'>
+ function clean_get(form) {
+ var inputs = $(form).find("input");
+ inputs.each(function() {
+ var el = $(this);
+ var val = $(this).val();
+ if (val === '' || (val === '0' && /.*gte/.test(el.name))) {
+ $(this).remove();
+ }
+ });
+ return true;
+ }
+ </script>
+ <form method='get' action='{% url afg.search %}' onsubmit='return clean_get(this);'>
<input type='text' value='{{ params.q }}' name='q' />
<input type='submit' value='search' />
+
{% for param, choice_opts in choices.items %}
<h2>{{ choice_opts.title }}</h2>
{% if choice_opts.value %}
@@ -24,14 +38,46 @@ <h2>{{ choice_opts.title }}</h2>
{% endfor %}
</ul>
{% endfor %}
+
{% for param, choice_opts in min_max_choices.items %}
<h2>{{ choice_opts.title }}</h2>
- <ul>
- <li>Minimum: <input class='minmax' size='2' type='text' value='{{ choice_opts.min_value }}' name='{{param}}__gte' /> ({{ choice_opts.min }})</li>
- <li>Maximum: <input class='minmax' size='2' type='text' value='{{ choice_opts.max_value }}' name='{{param}}__lte' /> ({{ choice_opts.max }})</li>
- </ul>
-
+ <div id='sparkline_{{param}}'></div>
+ <div id='slider_{{param}}'></div>
+ <div>
+ <div style='float: left;'>
+ <input name='{{param}}__gte' id='{{param}}__gte' value='{{ choice_opts.chosen_min }}' size=3 />
+ (min: {{ choice_opts.min_value }})
+ </div>
+ <div style='float: right;'>
+ (max: {{ choice_opts.max_value }})
+ <input name='{{param}}__lte' id='{{param}}__lte' value='{{ choice_opts.chosen_max }}' size=3 />
+ </div>
+ <div style='clear: both;'></div>
+ </div>
+ <script type='text/javascript'>
+ var vals = [{{choice_opts.counts|join:", "}}];
+ // remove '0' which out-ranges all other values
+ vals.splice(0, 1);
+ $('#sparkline_{{param}}').sparkline(vals, {width: '100%'});
+ var update = function(event, ui) {
+ var val = $(this).slider('option', 'values');
+ $("#{{param}}__gte").val(val[0]);
+ $("#{{param}}__lte").val(val[1]);
+ }
+ $('#slider_{{param}}').slider({
+ range: true,
+ values: [{% if choice_opts.chosen_min %} {{ choice_opts.chosen_min }}{% else %}{{ choice_opts.min_value }}{% endif %},
+ {% if choice_opts.chosen_max %} {{ choice_opts.chosen_max }}{% else %}{{ choice_opts.max_value }}{% endif %}],
+ max: {{ choice_opts.max_value }},
+ min: {{ choice_opts.min_value }},
+ change: update,
+ slide: update
+ });
+ </script>
{% endfor %}
+ <p style='text-align: center;'>
+ <input type='submit' value='Search' />
+ </p>
</form>
<hr>
<ul>
View
@@ -2,9 +2,12 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <link rel="stylesheet" type="text/css" media="all" href="{{MEDIA_URL}}css/style.css" />
<title>{% block title %}{% endblock %} -- Afghan War Diaries explorer</title>
+ <link rel="stylesheet" type="text/css" media="all" href="{{MEDIA_URL}}css/style.css" />
+ <link rel="stylesheet" type="text/css" media="all" href="{{MEDIA_URL}}css/cupertino/jquery-ui-1.8.4.custom.css" />
<script type='text/javascript' src='{{MEDIA_URL}}js/jquery.min.js'></script>
+ <script type='text/javascript' src='{{MEDIA_URL}}js/jquery-ui.custom.min.js'></script>
+ <script type='text/javascript' src='{{MEDIA_URL}}js/jquery.sparkline.min.js'></script>
<script type='text/javascript' src='{{MEDIA_URL}}js/script.js'></script>
{% block head %}{% endblock %}
</head>
View
@@ -101,7 +101,6 @@ def random_entry(request):
return utils.redirect_to("afg.show_entry", report_key)
def _excerpt(text, needles):
- print needles
if not needles:
i = 200
while i < len(text) and text[i] != " ":
@@ -182,7 +181,7 @@ def search(request, about=False, api=False):
text_facets = ('type_', 'region', 'attack_on', 'type_of_unit', 'affiliation',
'dcolor', 'classification', 'category')
- integer_facets = ('civilian_kia', 'civilian_wia', 'host_nation_kia', 'host_nation_wia',
+ integer_facets = ('total_casualties', 'civilian_kia', 'civilian_wia', 'host_nation_kia', 'host_nation_wia',
'friendly_kia', 'friendly_wia', 'enemy_kia', 'enemy_wia', 'enemy_detained')
# prepare fields for faceting. `date` is special-cased later.
for facet in text_facets:
@@ -199,46 +198,54 @@ def search(request, about=False, api=False):
# Narrow query set by given facets
for key,val in request.GET.iteritems():
if val:
- val == sqs.query.clean(val)
# Add an "exact" param and split by '__'. If the field already has
# e.g. __gte, the __exact addendum is ignored, since we only look
# at the first two parts.
field_name, lookup = (key + "__exact").rsplit(r'__')[0:2]
+ # "type" is a reserved name for Solr, so munge it to "type_"
field_name = "type_" if field_name == "type" else field_name
+ # Dates are handled specially below
+ if field_name == 'date':
+ continue
field = DiaryEntryIndex.fields.get(field_name, None)
if field:
+ val = sqs.query.clean(val)
+ print field, val
if lookup == 'exact':
sqs = sqs.narrow(u'%s:"%s"' % (field.index_fieldname, val))
elif lookup == 'gte':
- sqs = sqs.narrow(u"%s:[%s TO *]" % val)
+ sqs = sqs.narrow(u"%s:[%s TO *]" % (field.index_fieldname, val))
elif lookup == 'lte':
- sqs = sqs.narrow(u"%s:[* TO %s]" % val)
+ sqs = sqs.narrow(u"%s:[* TO %s]" % (field.index_fieldname, val))
else:
continue
params[key] = val
+
# Narrow query set by given dates
- day = int(request.GET.get('date__day', 0))
- month = int(request.GET.get('date__month', 0))
- year = int(request.GET.get('date__year', 0))
+ date = request.GET.get('date', '')
+ if date:
+ year, month, day = [int(d) for d in (date + "-0-0").split("-")[0:3]]
+ else:
+ # Legacy date format
+ day = int(request.GET.get('date__day', 0))
+ month = int(request.GET.get('date__month', 0))
+ year = int(request.GET.get('date__year', 0))
if year:
if not month:
start = datetime.datetime(year, 1, 1)
end = datetime.datetime(year + 1, 1, 1) - datetime.timedelta(seconds=1)
- params['date__year'] = year
+ params['date'] = start.strftime("%Y")
sqs = sqs.date_facet('date', start, end, 'month')
elif not day:
start = datetime.datetime(year, month, 1)
next_month = datetime.datetime(year, month, 1) + datetime.timedelta(days=31)
end = datetime.datetime(next_month.year, next_month.month, 1) - datetime.timedelta(seconds=1)
- params['date__year'] = year
- params['date__month'] = month
+ params['date'] = start.strftime("%Y-%m")
sqs = sqs.date_facet('date', start, end, 'day')
else:
start = datetime.datetime(year, month, day)
end = datetime.datetime(year, month, day + 1) - datetime.timedelta(seconds=1)
- params['date__year'] = year
- params['date__month'] = month
- params['date__day'] = day
+ params['date'] = start.strftime("%Y-%m-%d")
sqs = sqs.date_facet('date', start, end, 'day')
sqs = sqs.narrow("date:[%s TO %s]" % (start.isoformat() + "Z", end.isoformat() + "Z"))
else:
@@ -269,7 +276,7 @@ def search(request, about=False, api=False):
if entry.highlighted:
excerpt = mark_safe(u"... %s ..." % entry.highlighted['text'][0])
else:
- excerpt = entry.summary[0:200] + "..."
+ excerpt = (entry.summary or '')[0:200] + "..."
entries.append((entry, excerpt))
# Choices
@@ -287,45 +294,48 @@ def search(request, about=False, api=False):
pass
# Date choices
- choices['date__year'] = {
- 'title': 'Year',
- 'value': params.get('date__year', ''),
+ choices['date'] = {
+ 'title': 'Date',
+ 'value': params.get('date', ''),
}
- year = params.get('date__year', '')
+ year, month, day = (params.get('date', '') + "--").split("-")[0:3]
if year:
- choices['date__year']['choices'] = [(year, year, total_count)]
- month = params.get('date__month', '')
- choices['date__month'] = {
- 'title': 'Month',
- 'value': month
- }
if month:
- choices['date__month']['choices'] = [(date_facets[0][0].strftime("%B"), month, total_count)]
- day = params.get('date__day', '')
- choices['date__day'] = {
- 'title': 'Day',
- 'value': day
- }
if day:
- choices['date__day']['choices'] = [(day, day, total_count)]
+ d = datetime.date(int(year), int(month), int(day))
+ choices['date']['choices'] = [(d.strftime("%Y %B %e"), d.strftime("%Y-%m-%d"), total_count)]
else:
- choices['date__day']['choices'] = [(d.day, d.day, c) for d, c in date_facets]
+ choices['date']['choices'] = [(d.strftime("%B %e"), d.strftime("%Y-%m-%d"), c) for d, c in date_facets]
else:
- choices['date__month']['choices'] = [(d.strftime("%B"), d.month, c) for d, c in date_facets]
+ choices['date']['choices'] = [(d.strftime("%B"), d.strftime("%Y-%m"), c) for d, c in date_facets]
else:
- choices['date__year']['choices'] = [(d.year, d.year, c) for d, c in date_facets]
- params.pop('date__month', '')
- params.pop('date__day', '')
+ choices['date']['choices'] = [(d.year, d.year, c) for d, c in date_facets]
# Text field choices
- for field in text_facets + integer_facets:
+ for field in text_facets:
choices[field] = {
'title': field.replace('_', ' ').title(),
'choices': sorted((k, k, c) for k, c in counts['fields'][field] if c > 0),
'value': params.get(field, ''),
}
+ # Integer choices
min_max_choices = utils.OrderedDict()
+ for field in integer_facets:
+ facets = sorted([(int(k), v) for k,v in counts['fields'][field]])
+ min_max_choices[field] = {
+ 'title': fix_constraint_name(field),
+ 'counts': [v for k,v in facets],
+ 'min_value': facets[0][0],
+ 'max_value': facets[-1][0],
+ 'min_count': facets[0][1],
+ 'max_count': facets[-1][1],
+ 'chosen_min': params.get(field + '__gte', ''),
+ 'chosen_max': params.get(field + '__lte', ''),
+ }
+
+
+
# # Integer choices
# for field in integer_facets:
# try:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.

0 comments on commit 3e1599c

Please sign in to comment.