Skip to content
Snippets Groups Projects
Verified Commit 189177f9 authored by Owen Graham's avatar Owen Graham
Browse files

Unify plotter templates

parent cc4f8577
No related branches found
No related tags found
No related merge requests found
...@@ -44,7 +44,7 @@ def render_plotter(name, embedded): ...@@ -44,7 +44,7 @@ def render_plotter(name, embedded):
g.record_years = dict(map(id_years, stations)) g.record_years = dict(map(id_years, stations))
g.all_years = sorted(set(year for years in g.record_years.values() g.all_years = sorted(set(year for years in g.record_years.values()
for year in years)) for year in years))
return render_template(f'plotters/{name}.html') return render_template('plotter.html')
@app.route('/source') @app.route('/source')
......
...@@ -5,18 +5,22 @@ from flask import abort, request ...@@ -5,18 +5,22 @@ from flask import abort, request
from .data import measurements from .data import measurements
def get_param(key, to=str): def get_param(key, to=str, call_abort=True):
"""Get a parameter from the query string. """Get a parameter from the query string.
Calls `abort(400)` if the value is the wrong type or missing. Can call `abort(400)` if the value is the wrong type or missing.
""" """
val = request.args.get(key) val = request.args.get(key)
if val is None: if val is None:
abort(400) if call_abort:
abort(400)
return None
try: try:
return to(val) return to(val)
except ValueError: except ValueError:
abort(400) if call_abort:
abort(400)
return None
def meas_type(s): def meas_type(s):
......
...@@ -17,6 +17,28 @@ plt.rcParams['axes.xmargin'] = 0 ...@@ -17,6 +17,28 @@ plt.rcParams['axes.xmargin'] = 0
matplotlib.use('Agg') matplotlib.use('Agg')
class Selector:
"""Information about a `<select>`."""
def __init__(self, **kwargs):
if kwargs['type'] not in ('station', 'year', 'measurement'):
raise ValueError('unknown type')
self.type = kwargs['type']
self.name = kwargs['name']
self.id = kwargs['id']
self.label = kwargs['label']
self.onchange = kwargs.get('onchange')
def get_param(self):
if self.type == 'year':
to = year_type
elif self.type == 'measurement':
to = meas_type
else:
to = str
return get_param(self.name, to=to, call_abort=False)
class Plotter: class Plotter:
"""Parent of plotter classes.""" """Parent of plotter classes."""
...@@ -26,6 +48,15 @@ class TimeSeries(Plotter): ...@@ -26,6 +48,15 @@ class TimeSeries(Plotter):
name = 'time-series' name = 'time-series'
nav_title = 'Time Series' nav_title = 'Time Series'
page_title = 'Plot Data'
onsubmit_fn = 'timeSeriesVisualize'
selectors = (
Selector(type='station', name='station', id='station', label='Station',
onchange='getYears()'),
Selector(type='year', name='year', id='year', label='Year'),
Selector(type='measurement', name='measurement', id='measurement',
label='Measurement'),
)
@classmethod @classmethod
def plot(cls): def plot(cls):
...@@ -68,6 +99,18 @@ class Overlay(Plotter): ...@@ -68,6 +99,18 @@ class Overlay(Plotter):
name = 'overlay' name = 'overlay'
nav_title = 'Overlay' nav_title = 'Overlay'
page_title = 'Overlay Stations'
onsubmit_fn = 'overlayVisualize'
selectors = (
Selector(type='station', name='station1', id='station-1',
label='Station #1', onchange='getYears(1)'),
Selector(type='year', name='year1', id='year-1', label='Year #1'),
Selector(type='station', name='station2', id='station-2',
label='Station #2', onchange='getYears(2)'),
Selector(type='year', name='year2', id='year-2', label='Year #2'),
Selector(type='measurement', name='measurement', id='measurement',
label='Measurement'),
)
@classmethod @classmethod
def plot(cls): def plot(cls):
...@@ -138,6 +181,16 @@ class Boxplot(Plotter): ...@@ -138,6 +181,16 @@ class Boxplot(Plotter):
name = 'boxplot' name = 'boxplot'
nav_title = 'Boxplot' nav_title = 'Boxplot'
page_title = 'Boxplot Years'
onsubmit_fn = 'boxplotVisualize'
selectors = (
Selector(type='station', name='station', id='station', label='Station',
onchange='boxplotGetYears()'),
Selector(type='year', name='year1', id='year-1', label='Year #1'),
Selector(type='year', name='year2', id='year-2', label='Year #2'),
Selector(type='measurement', name='measurement', id='measurement',
label='Measurement'),
)
@classmethod @classmethod
def plot(cls): def plot(cls):
......
...@@ -13,6 +13,12 @@ ...@@ -13,6 +13,12 @@
</nav> </nav>
{% endmacro %} {% endmacro %}
{% macro onchange(js) -%}
{%- if js is not none %} onchange="{{ js }}"{% endif -%}
{%- endmacro %}
{% macro station_options(selected=none) %} {% macro station_options(selected=none) %}
{% for station in g.stations %} {% for station in g.stations %}
<option value="{{ station['id'] }}" <option value="{{ station['id'] }}"
...@@ -33,12 +39,19 @@ ...@@ -33,12 +39,19 @@
{% macro measurement_options(selected=none) %} {% macro measurement_options(selected=none) %}
{% for meas in g.measurements.values() %} {% for meas in g.measurements.values() %}
<option value="{{ meas.slug }}" <option value="{{ meas.slug }}"
{{- _selected(meas.slug == selected) }}> {{- _selected(meas == selected) }}>
{{- meas.title -}} {{- meas.title -}}
</option> </option>
{% endfor %} {% endfor %}
{% endmacro %} {% endmacro %}
{% set options = {
'station': station_options,
'year': year_options,
'measurement': measurement_options,
} %}
{% macro _selected(is_selected) %} {% macro _selected(is_selected) %}
{%- if is_selected %} selected{% endif -%} {%- if is_selected %} selected{% endif -%}
{% endmacro %} {% endmacro %}
{% extends 'base.html' %}
{% set plotter_title = g.plotter.page_title %}
{% block content -%}
<form id="controls" onsubmit="{{ g.plotter.onsubmit_fn }}(); return false;"
method="get" action="{{ url_for('plot_image', name=g.plotter.name) }}">
<div id="selections">
{% for sel in g.plotter.selectors %}
<div>
<label for="{{ sel.id }}">{{ sel.label }}</label>
<select name="{{ sel.name }}" id="{{ sel.id }}" required
{{- macros.onchange(sel.onchange) }}>
<option value="">Select {{ sel.label }}</option>
{{ macros.options[sel.type](sel.get_param()) | trim }}
</select>
</div>
{% endfor %}
</div>
<input type="submit" value="Visualize">
</form>
{%- endblock %}
{% extends 'base.html' %}
{% set plotter_title %}Boxplot Years{% endset %}
{% block content -%}
<form id="controls" onsubmit="boxplotVisualize(); return false;"
method="get" action="{{ url_for('plot_image', name='boxplot') }}">
<div id="selections">
<div>
<label for="station">Station</label>
<select name="station" id="station" required onchange="boxplotGetYears()">
<option value="">Select Station</option>
{{ macros.station_options(request.args.get('station')) | trim }}
</select>
</div>
<div>
<label for="year-1">Year #1</label>
<select name="year1" id="year-1" required>
<option value="">Select Year #1</option>
{{ macros.year_options(request.args.get('year1') | int) | trim }}
</select>
</div>
<div>
<label for="year-2">Year #2</label>
<select name="year2" id="year-2" required>
<option value="">Select Year #2</option>
{{ macros.year_options(request.args.get('year2') | int) | trim }}
</select>
</div>
<div>
<label for="measurement">Measurement</label>
<select name="measurement" id="measurement" required>
<option value="">Select Measurement</option>
{{ macros.measurement_options(request.args.get('measurement')) | trim }}
</select>
</div>
</div>
<input type="submit" value="Visualize">
</form>
{%- endblock %}
{% extends 'base.html' %}
{% set plotter_title %}Overlay Stations{% endset %}
{% block content -%}
<form id="controls" onsubmit="overlayVisualize(); return false;"
method="get" action="{{ url_for('plot_image', name='overlay') }}">
<div id="selections">
<div>
<label for="station-1">Station #1</label>
<select name="station1" id="station-1" required onchange="getYears(1)">
<option value="">Select Station #1</option>
{{ macros.station_options(request.args.get('station1')) | trim }}
</select>
</div>
<div>
<label for="year-1">Year #1</label>
<select name="year1" id="year-1" required>
<option value="">Select Year #1</option>
{{ macros.year_options(request.args.get('year1') | int) | trim }}
</select>
</div>
<div>
<label for="station-2">Station #2</label>
<select name="station2" id="station-2" required onchange="getYears(2)">
<option value="">Select Station #2</option>
{{ macros.station_options(request.args.get('station2')) | trim }}
</select>
</div>
<div>
<label for="year-2">Year #2</label>
<select name="year2" id="year-2" required>
<option value="">Select Year #2</option>
{{ macros.year_options(request.args.get('year2') | int) | trim }}
</select>
</div>
<div>
<label for="measurement">Measurement</label>
<select name="measurement" id="measurement" required>
<option value="">Select Measurement</option>
{{ macros.measurement_options(request.args.get('measurement')) | trim }}
</select>
</div>
</div>
<input type="submit" value="Visualize">
</form>
{%- endblock %}
{% extends 'base.html' %}
{% set plotter_title %}Plot Data{% endset %}
{% block content -%}
<form id="controls" onsubmit="timeSeriesVisualize(); return false;"
method="get" action="{{ url_for('plot_image', name='time-series') }}">
<div id="selections">
<div>
<label for="station">Station</label>
<select name="station" id="station" required onchange="getYears()">
<option value="">Select Station</option>
{{ macros.station_options(request.args.get('station')) | trim }}
</select>
</div>
<div>
<label for="year">Year</label>
<select name="year" id="year" required>
<option value="">Select Year</option>
{{ macros.year_options(request.args.get('year') | int) | trim }}
</select>
</div>
<div>
<label for="measurement">Measurement</label>
<select name="measurement" id="measurement" required>
<option value="">Select Measurement</option>
{{ macros.measurement_options(request.args.get('measurement')) | trim }}
</select>
</div>
</div>
<input type="submit" value="Visualize">
</form>
{%- endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment