From 1fd0dd8b28bac19431a8c577ee78ea655882ad82 Mon Sep 17 00:00:00 2001 From: Gertjan van den Burg Date: Wed, 31 Jul 2019 16:28:31 +0100 Subject: Add support for multidimensional datasets --- app/admin/routes.py | 4 +- app/main/demo.py | 31 +++ app/main/routes.py | 5 +- app/static/css/admin/view_annotation.css | 6 + app/static/css/demo/evaluate.css | 5 + app/static/css/main/annotate.css | 5 + app/static/js/buttons.js | 14 +- app/static/js/makeChart.js | 1 - app/static/js/makeChartMulti.js | 319 ++++++++++++++++++++++++ app/static/js/updateTable.js | 74 ++++++ app/templates/admin/annotations_by_dataset.html | 4 + app/templates/annotate/index.html | 6 +- app/templates/demo/evaluate.html | 37 +-- 13 files changed, 485 insertions(+), 26 deletions(-) create mode 100644 app/static/js/makeChartMulti.js (limited to 'app') diff --git a/app/admin/routes.py b/app/admin/routes.py index b8ca81b..9b7688b 100644 --- a/app/admin/routes.py +++ b/app/admin/routes.py @@ -129,7 +129,7 @@ def manage_users(): @admin_required def manage_datasets(): dataset_list = [(d.id, d.name) for d in Dataset.query.all()] - dataset_list.sort(key=lambda x : x[1]) + dataset_list.sort(key=lambda x: x[1]) form = AdminManageDatasetsForm() form.dataset.choices = dataset_list @@ -281,11 +281,13 @@ def view_annotations_by_dataset(dset_id): anno_clean.append(dict(user=uid, index=ann.cp_index)) data = load_data_for_chart(dataset.name, dataset.md5sum) + is_multi = len(data["chart_data"]["values"]) > 1 data["annotations"] = anno_clean return render_template( "admin/annotations_by_dataset.html", title="View Annotations for dataset", data=data, + is_multi=is_multi, ) diff --git a/app/main/demo.py b/app/main/demo.py index afb7f61..2edae04 100644 --- a/app/main/demo.py +++ b/app/main/demo.py @@ -252,6 +252,32 @@ DEMO_DATA = { ) }, }, + 8: { + "dataset": {"name": "demo_800"}, + "learn": { + "text": markdown.markdown( + textwrap.dedent( + """ + In practice time series datasets are not just one + dimensional, but can be multidimensional too. A change + point in such a time series does not necessarily occur in + all dimensions simultaneously. It is therefore important to + evaluate the behaviour of each dimension individually, as + well as in relation to the others.""" + ) + ) + }, + "annotate": {"text": RUBRIC}, + "evaluate": { + "text": markdown.markdown( + textwrap.dedent( + """ + In this example of a multidimensional time series, the + change only occurred in a single dimension.""" + ) + ) + }, + }, } @@ -373,13 +399,16 @@ def demo_annotate(demo_id): "error", ) return redirect(url_for("main.index")) + chart_data = load_data_for_chart(dataset.name, dataset.md5sum) + is_multi = len(chart_data["chart_data"]["values"]) > 1 return render_template( "annotate/index.html", title="Introduction – %i" % demo_id, data=chart_data, rubric=demo_data["text"], identifier=demo_id, + is_multi=is_multi, ) @@ -398,6 +427,7 @@ def demo_evaluate(demo_id, phase_id, form): name=DEMO_DATA[demo_id]["dataset"]["name"] ).first() chart_data = load_data_for_chart(dataset.name, dataset.md5sum) + is_multi = len(chart_data["chart_data"]["values"]) > 1 true_changepoints = get_demo_true_cps(dataset.name) if true_changepoints is None: flash( @@ -415,6 +445,7 @@ def demo_evaluate(demo_id, phase_id, form): annotations_true=annotations_true, text=demo_data["text"], form=form, + is_multi=is_multi ) diff --git a/app/main/routes.py b/app/main/routes.py index ad78f27..02ec7c9 100644 --- a/app/main/routes.py +++ b/app/main/routes.py @@ -18,7 +18,8 @@ logger = logging.getLogger(__name__) RUBRIC = """ Please mark the point(s) in the time series where an abrupt change in the behaviour of the series occurs. The goal is to define segments of the time - series that are separated by places where these abrupt changes occur. + series that are separated by places where these abrupt changes occur. Recall + that it is also possible for there to be no such changes.
""" @@ -112,10 +113,12 @@ def annotate(task_id): flash( "An internal error occurred loading this dataset, the admin has been notified. Please try again later. We apologise for the inconvenience." ) + is_multi = len(data["chart_data"]["values"]) > 1 return render_template( "annotate/index.html", title=task.dataset.name.title(), identifier=task.id, data=data, rubric=RUBRIC, + is_multi=is_multi, ) diff --git a/app/static/css/admin/view_annotation.css b/app/static/css/admin/view_annotation.css index 11bf3c8..09d5a4d 100644 --- a/app/static/css/admin/view_annotation.css +++ b/app/static/css/admin/view_annotation.css @@ -9,6 +9,12 @@ clip-path: url(#clip); } +.z-line line { + stroke: #ccc; + shape-rendering: crispEdges; +} + + .ann-line { fill: none; stroke-dasharray: 5; diff --git a/app/static/css/demo/evaluate.css b/app/static/css/demo/evaluate.css index 0c7dbc2..aea3162 100644 --- a/app/static/css/demo/evaluate.css +++ b/app/static/css/demo/evaluate.css @@ -19,6 +19,11 @@ clip-path: url(#clip); } +.z-line line { + stroke: #ccc; + shape-rendering: crispEdges; +} + circle { clip-path: url(#clip); fill: blue; diff --git a/app/static/css/main/annotate.css b/app/static/css/main/annotate.css index 595f2a2..d1ff2b3 100644 --- a/app/static/css/main/annotate.css +++ b/app/static/css/main/annotate.css @@ -9,6 +9,11 @@ clip-path: url(#clip); } +.z-line line { + stroke: #ccc; + shape-rendering: crispEdges; +} + circle { clip-path: url(#clip); fill: blue; diff --git a/app/static/js/buttons.js b/app/static/js/buttons.js index 75adad2..edd3f56 100644 --- a/app/static/js/buttons.js +++ b/app/static/js/buttons.js @@ -47,15 +47,19 @@ function submitOnClick(identifier) { var obj = {}; obj["identifier"] = identifier; obj["changepoints"] = []; - var i, cp; + + var i, cp, xval, seen = []; for (i=0; i + {% if is_multi %} + + {% else %} + {% endif %} - + {% if is_multi %} + + {% else %} + + {% endif %} - - - +{% block scripts %} + {{ super() }} + + {% if is_multi %} + + {% else %} + + {% endif %} + + {% endblock %} -- cgit v1.2.3