From e6b57ce78948d73ed4af3faf8957f6d30752559d Mon Sep 17 00:00:00 2001 From: lkrsnik Date: Thu, 26 Dec 2024 15:30:00 +0100 Subject: [PATCH] Added detailed examples endpoint and modified results. --- app.py | 65 +++++++++++++++++++++++++++++++-- static/js/examples.js | 79 +++++++++++++++++++++++++++++++++++++++++ static/js/result.js | 13 +++++-- templates/examples.html | 76 +++++++++++++++++++++++++++++++++++++++ templates/result.html | 44 +++++++++++++---------- 5 files changed, 253 insertions(+), 24 deletions(-) create mode 100644 static/js/examples.js create mode 100644 templates/examples.html diff --git a/app.py b/app.py index 3236cb7..b38e9a1 100755 --- a/app.py +++ b/app.py @@ -1,5 +1,6 @@ import configparser import csv +import hashlib import json import os import random @@ -130,10 +131,65 @@ def create_app(): for subtree_id in subtree_ids: annodoc += f'# visual-style {subtree_id} bgColor:lightgreen\n' with open(os.path.join('media', result_id, 'annodoc', sentence_id), 'r') as rf: - # annodoc += '\n'.join(rf.readlines()) annodoc += rf.read() + '\n\n' return {'annodoc': annodoc} - # return '
' + annodoc + '
' + + @app.route('/stark/result//', methods=['GET']) + def examples(result_id, subtree_hash): + # find example details + with open(os.path.join('media', result_id, 'result.tsv'), 'r') as rf: + content = list(csv.reader(rf, delimiter='\t')) + head = content[0] + content_dict = {h: [] for h in head} + table_columns2displayed_table_columns = { + 'Tree': gettext('Tree'), + 'Absolute frequency': gettext('Frequency'), + 'Absolute frequency in second treebank': gettext('Frequency in B'), + 'Order': gettext('Order'), + 'Number of nodes': gettext('Number of nodes'), + 'Head node': gettext('Head node'), + 'Grew-match URL': gettext('Grew-match URL'), + 'Ratio': gettext('Ratio'), + '%DIFF': gettext('%DIFF'), + 'OR': gettext('OR'), + 'BIC': gettext('BIC'), + 'MI': gettext('MI'), + 'logDice': gettext('logDice'), + 't-score': gettext('t-score') + } + if 'Absolute frequency in second treebank' in head: + table_columns2displayed_table_columns['Absolute frequency'] = gettext('Frequency in A') + else: + del table_columns2displayed_table_columns['Absolute frequency in second treebank'] + displayed_table_columns2table_columns = {v: k for k, v in table_columns2displayed_table_columns.items()} + + annodoc_index = head.index('Annodoc') + + selected_content = [row for row in content[1:] + if json.loads(row[annodoc_index])['subtree_hash'] == subtree_hash] + + for i, row in enumerate(selected_content): + for j, v in enumerate(row): + content_dict[head[j]].append(v) + + head = [(k, v) for k, v in table_columns2displayed_table_columns.items() if k in head] + + displayed_content_dict = {} + for f_h, h in head: + if f_h == '%DIFF' or f_h == 'OR': + displayed_content_dict[f_h] = [sci_notation(eval(n)) for n in + content_dict[displayed_table_columns2table_columns[h]]] + else: + displayed_content_dict[f_h] = content_dict[displayed_table_columns2table_columns[h]] + + # add visualization parts to dict + visualization_dict = {'example_id': [], 'example_positions': []} + with open(os.path.join('media', result_id, 'annodoc_detailed', subtree_hash), 'r') as rf: + for vis in list(csv.reader(rf, delimiter='\t')): + visualization_dict['example_id'].append(vis[0]) + visualization_dict['example_positions'].append('+'.join(map(str, eval(vis[1])))) + + return render_template('examples.html', head=head, content=displayed_content_dict, visualization=visualization_dict) @app.route('/stark/result/', methods=['GET', 'POST']) def result(result_id): @@ -158,6 +214,7 @@ def create_app(): with open(os.path.join('media', result_id, 'result.tsv'), 'r') as rf: content = list(csv.reader(rf, delimiter='\t')) + content = [con + [str(i)] for i, con in enumerate(content)] head = content[0] content_dict = {h: [] for h in head} table_columns2displayed_table_columns = { @@ -215,7 +272,7 @@ def create_app(): annodoc_data = [json.loads(el) for el in content_dict['Annodoc']] displayed_content_dict['example_id'] = [el['id'] for el in annodoc_data] displayed_content_dict['example_positions'] = ['+'.join([str(p) for p in el['positions']]) for el in annodoc_data] - + displayed_content_dict['subtree_hash'] = [el['subtree_hash'] for el in annodoc_data] return render_template('result.html', head=head, content=displayed_content_dict) @@ -380,6 +437,8 @@ def create_app(): configs['output'] = os.path.join(output_path, 'result.tsv') configs['annodoc_example_dir'] = os.path.join(output_path, 'annodoc') + configs['annodoc_detailed_dir'] = os.path.join(output_path, 'annodoc_detailed') + configs['detailed_results_file'] = os.path.join(output_path, 'detailed_results_file.tsv') if len(validation) > 0: return render_template('index.html', validation=validation, translations=translations) try: diff --git a/static/js/examples.js b/static/js/examples.js new file mode 100644 index 0000000..b4ade34 --- /dev/null +++ b/static/js/examples.js @@ -0,0 +1,79 @@ + +$(document).ready(function() { + const visualizations = $(".visualization"); + const batchSize = 10; + let startIndex = 0; + let loading = false; // Flag to prevent multiple simultaneous loads + + $(".visualization").closest("tr").prev("tr").hide(); + $(".visualization").closest("tr").hide(); + + function loadVisualizations(start, count) { + if (loading) return; // Prevent concurrent loads + loading = true; + + const visualizationsToLoad = visualizations.slice(start, start + count); + let promises = []; + + visualizationsToLoad.each(function() { + var $this = $(this); // Cache $(this) for better performance + var example_id = $this.data("example-id"); + var example_positions = $this.data("example-positions"); + var window_location = window.location.pathname.split("/"); + var subtree_hash = window_location.pop(); // This line overwrites the earlier subtree_hash, is this intended? + var dir_name = window_location.pop(); + var url = window.location.origin + '/stark/visualization/' + dir_name + '/' + example_id + '/' + example_positions; + + promises.push($.ajax({ + url: url, + success: function(result) { + var escapedHtml = `
${result['annodoc']}
`; + $this.html(escapedHtml); + $('.conllu', $this).each(function() { + Annodoc.embedAnnotation($(this), Annodoc.parseConllU, Config.bratCollData); + }); + $this.closest("tr").prev("tr").show(); + $this.closest("tr").show(); + }, + error: function(jqXHR, textStatus, errorThrown) { + console.error("AJAX Error:", textStatus, errorThrown); + $this.html("

Error loading data.

"); + $this.closest("tr").prev("tr").show(); + $this.closest("tr").show(); + }, + complete: function() { + // Check if all AJAX calls in the current batch are complete + if (promises.every(p => p.state() === 'resolved' || p.state() === 'rejected')) { + loading = false; // Allow further loading + } + } + })); + }); + } + + function checkScroll() { + if ($(window).scrollTop() + $(window).height() >= $(document).height() - 200 && !loading) { // 200px buffer + loadVisualizations(startIndex, batchSize); + startIndex += batchSize; + } + } + + // Initial load + if (typeof head !== 'undefined' && typeof head.ready === 'function') { + head.ready(function() { + loadVisualizations(startIndex, batchSize); + startIndex += batchSize; + }); + } else { + if (typeof Annodoc !== 'undefined') { + loadVisualizations(startIndex, batchSize); + startIndex += batchSize; + } else { + console.error("head.js or Annodoc is not available. Ensure they are loaded correctly."); + } + } + + + $(window).scroll(checkScroll); // Attach scroll event listener + +}); \ No newline at end of file diff --git a/static/js/result.js b/static/js/result.js index 0185c2a..2da676b 100644 --- a/static/js/result.js +++ b/static/js/result.js @@ -23,10 +23,14 @@ $(document).ready(function() { $(".table-wrapper tbody tr").click(function() { $(".visualization-table").show(); var grew_url = $(this).data("href"); + var subtree_hash = $(this).data("subtree-hash"); var example_id = $(this).data("exid"); + var grew_link_text = $(this).data("grew-link-text"); + var other_examples_text = $(this).data("other-examples-text"); var example_positions = $(this).data("expositions"); var dir_name = window.location.pathname.split("/").pop() - var url = window.location.origin + '/stark/visualization/' + dir_name + '/' + example_id + '/' + example_positions + var other_examples = window.location.origin + '/stark/result/' + dir_name + '/' + subtree_hash; + var url = window.location.origin + '/stark/visualization/' + dir_name + '/' + example_id + '/' + example_positions; $.ajax({url: url, success: function(result){ var escapedHtml = `
${result['annodoc']}
`; $(".visualization").html(escapedHtml); @@ -37,7 +41,12 @@ $(document).ready(function() { if (grew_url == 'unknown') { $(".grew-link").html("/"); } else { - $(".grew-link").html("GREW link"); + $(".grew-link").html("" + grew_link_text + ""); + } + if (other_examples == 'unknown') { + $(".other-examples").html("/"); + } else { + $(".other-examples").html("" + other_examples_text + ""); } }); $(".th-desc").hide(); diff --git a/templates/examples.html b/templates/examples.html new file mode 100644 index 0000000..3c5b049 --- /dev/null +++ b/templates/examples.html @@ -0,0 +1,76 @@ +{% extends "base.html" %} + +{% block custom_css %} + + +{% endblock %} +{% block content %} +
+
+ + + +
{{ _('Examples') }}
+
+
+
+ + + + {% for h, h_t in head %} + {% if not h == 'Grew-match URL' %} + + {% endif %} + {% endfor %} + + + + {% for i in range(content['Tree']|length) %} + + {% for col in content %} + {% if not (col == 'Grew-match URL') %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
{{ h_t }}
+
+
+
+ + + + + + + + {% for i in range(visualization['example_id']|length) %} + + + + + + + {% endfor %} + +
{{ _('Examples') }}
ID: {{visualization['example_id'][i]}}
+ + + + + + + +
+
+
+
+
+{% endblock %} +{% block custom_js %} + + + +{% endblock %} diff --git a/templates/result.html b/templates/result.html index 51a8456..c8f426d 100644 --- a/templates/result.html +++ b/templates/result.html @@ -25,6 +25,29 @@ +
+ + + + + + + + + + + +
{{ _('Visualization') }}
+ + + + + + + +
+
+
@@ -38,9 +61,9 @@ {% for i in range(content['Tree']|length) %} - + {% for col in content %} - {% if not (col == 'Grew-match URL' or col == 'example_id' or col == 'example_positions') %} + {% if not (col == 'Grew-match URL' or col == 'example_id' or col == 'example_positions' or col == 'subtree_hash') %} {% endif %} {% endfor %} @@ -49,23 +72,6 @@
-
-
- - - - - - - - - - - - - -
VisualizationGrew
-