From 909471a6e58df80fbcb289d8bfcc2a1d6b4db2b6 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 9 Jul 2019 19:02:09 +0200 Subject: Graph generation: manage link - display raw SVG - scale SVG - manage reopening in a specific tab --- .../templates/ishtar/sheet_contextrecord.html | 20 +++++----- archaeological_context_records/views.py | 2 +- install/ishtar-install | 1 + .../ishtar/blocks/sheet_relation_image.html | 10 ++++- ishtar_common/templates/ishtar/sheet.html | 8 +++- ishtar_common/templatetags/ishtar_helpers.py | 11 ++++-- ishtar_common/utils.py | 46 ++++++++++++++++++---- requirements.txt | 1 + scss/custom.scss | 9 +++++ 9 files changed, 84 insertions(+), 24 deletions(-) diff --git a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html index 284ea7f32..e8c9e9a43 100644 --- a/archaeological_context_records/templates/ishtar/sheet_contextrecord.html +++ b/archaeological_context_records/templates/ishtar/sheet_contextrecord.html @@ -258,11 +258,11 @@ {% if item.relation_image or DOT_GENERATION %} {% with gen_url='generate-relation-image-contextrecord' %} -

{% trans "Diagram of statigraphic relations - full" %}

- {% with relation_type="" %} - {% with relation_image=item.relation_image %} - {% with relation_png=item.relation_bitmap_image %} - {% with relation_dot=item.relation_dot %} +

{% trans "Diagram of statigraphic relations - above" %}

+ {% with relation_type="above" %} + {% with relation_image=item.relation_image_above %} + {% with relation_png=item.relation_bitmap_image_above %} + {% with relation_dot=item.relation_dot_above %} {% include "ishtar/blocks/sheet_relation_image.html" %} {% endwith %}{% endwith %}{% endwith %}{% endwith %} @@ -274,11 +274,11 @@ {% include "ishtar/blocks/sheet_relation_image.html" %} {% endwith %}{% endwith %}{% endwith %}{% endwith %} -

{% trans "Diagram of statigraphic relations - above" %}

- {% with relation_type="above" %} - {% with relation_image=item.relation_image_above %} - {% with relation_png=item.relation_bitmap_image_above %} - {% with relation_dot=item.relation_dot_above %} +

{% trans "Diagram of statigraphic relations - full" %}

+ {% with relation_type="" %} + {% with relation_image=item.relation_image %} + {% with relation_png=item.relation_bitmap_image %} + {% with relation_dot=item.relation_dot %} {% include "ishtar/blocks/sheet_relation_image.html" %} {% endwith %}{% endwith %}{% endwith %}{% endwith %} diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index fbe382623..5b858a76a 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -168,7 +168,7 @@ class GenerateRelationImage(IshtarMixin, LoginRequiredMixin, RedirectView): def get_redirect_url(self, *args, **kwargs): return reverse('display-item', - args=[self.model.SLUG, self.item.pk]) + args=[self.model.SLUG, self.item.pk]) + "#relations" def get(self, request, *args, **kwargs): try: diff --git a/install/ishtar-install b/install/ishtar-install index f3dbfe189..82e31d002 100755 --- a/install/ishtar-install +++ b/install/ishtar-install @@ -468,6 +468,7 @@ EOF ( set -x; $sh_c 'sleep 3; apt-get install -y -q \ libpangocairo-1.0-0 python3-requests \ python3-bs4 python3-cffi pandoc libjs-jquery graphviz \ + python3-xmltodict \ python3-tidylib python3-lxml python3-imaging python3-html5lib \ python3-psycopg2 python3-gdal gettext memcached \ python3-memcache python3-dbf python3-markdown \ diff --git a/ishtar_common/templates/ishtar/blocks/sheet_relation_image.html b/ishtar_common/templates/ishtar/blocks/sheet_relation_image.html index 552dc5adc..f636f0b50 100644 --- a/ishtar_common/templates/ishtar/blocks/sheet_relation_image.html +++ b/ishtar_common/templates/ishtar/blocks/sheet_relation_image.html @@ -1,9 +1,17 @@ -{% load i18n %}{% if relation_image %} +{% load i18n ishtar_helpers %}{% if relation_image %} +
+{{relation_image|file_content|safe}} +
+{% comment %} + + +
{% if output != "ODT" %}{% endif %} {% if output != "ODT" %}{% endif %}
+{% endcomment %} {% endif %} {% if DOT_GENERATION and output != "ODT" and output != "PDF" %} diff --git a/ishtar_common/templates/ishtar/sheet.html b/ishtar_common/templates/ishtar/sheet.html index 6b9c97948..0dda760b8 100644 --- a/ishtar_common/templates/ishtar/sheet.html +++ b/ishtar_common/templates/ishtar/sheet.html @@ -73,7 +73,7 @@ {% block toolbar %}{% endblock %} {% endif %}
- {% if output != "ODT" and output != "PDF"%} + {% if output != "ODT" and output != "PDF" %} {% block head_sheet %} {% endblock %} diff --git a/ishtar_common/templatetags/ishtar_helpers.py b/ishtar_common/templatetags/ishtar_helpers.py index 88dd68b57..b6040487a 100644 --- a/ishtar_common/templatetags/ishtar_helpers.py +++ b/ishtar_common/templatetags/ishtar_helpers.py @@ -1,10 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from datetime import datetime - from django.template import Library -from django.utils.translation import ugettext as _ +from django.utils.text import mark_safe register = Library() @@ -17,3 +15,10 @@ def or_(value1, value2): @register.filter def and_(value1, value2): return value1 and value2 + + +@register.filter +def file_content(value): + if value: + return mark_safe(value.read()) + return "" diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index eb8414ced..43603b2e1 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -36,6 +36,7 @@ import six import subprocess import sys import tempfile +import xmltodict import zipfile from django import forms @@ -1224,15 +1225,22 @@ def generate_relation_graph(obj, highlight_current=True, above_relations, equal_relations, styles = get_relations_for_graph( rel_model, obj.pk, render_above=render_above, render_bellow=render_bellow, full=full) - if not above_relations and not equal_relations: - obj.relation_image = None - obj.save() - return # generate dotfile dot_str = "digraph relations {\nnode [shape=box];\n" rel_str = "" described = [] + if not above_relations and not equal_relations: + rel_str += "subgraph NoDir {\nedge [dir=none,style=dashed];\n" + style = 'label="{}"'.format(obj.relation_label) + if highlight_current: + style += ',style=filled,fillcolor="#C6C0C0"' + dot_str += u'item{}[{},href="{}"];\n'.format( + obj.pk, style, + reverse('display-item', + args=[model.SLUG, obj.pk]) + ) + rel_str += "}\n" for list, directed in ((above_relations, True), (equal_relations, False)): if directed: @@ -1246,14 +1254,20 @@ def generate_relation_graph(obj, highlight_current=True, style = 'label="{}"'.format(left.relation_label) if left.pk == obj.pk and highlight_current: style += ',style=filled,fillcolor="#C6C0C0"' - dot_str += u'item{}[{}];\n'.format(left.pk, style) + dot_str += u'item{}[{},href="{}"];\n'.format( + left.pk, style, + reverse('display-item', args=[model.SLUG, left.pk]) + ) if right_pk not in described: described.append(right_pk) right = model.objects.get(pk=right_pk) style = 'label="{}"'.format(right.relation_label) if right.pk == obj.pk and highlight_current: style += ',style=filled,fillcolor="#C6C0C0"' - dot_str += u'item{}[{}];\n'.format(right.pk, style) + dot_str += u'item{}[{},href="{}"];\n'.format( + right.pk, style, + reverse('display-item', args=[model.SLUG, right.pk]) + ) if not directed: # on the same level rel_str += u"{{rank = same; item{}; item{};}}\n".format( left_pk, right_pk) @@ -1270,9 +1284,9 @@ def generate_relation_graph(obj, highlight_current=True, dot_file.write(dot_str) if not render_above: - suffix = "_above" - elif not render_bellow: suffix = "_bellow" + elif not render_bellow: + suffix = "_above" else: suffix = "" @@ -1293,6 +1307,22 @@ def generate_relation_graph(obj, highlight_current=True, with open(svg_tmp_name, "w") as svg_file: popen = subprocess.Popen(args, stdout=svg_file) popen.wait() + + # scale image if necessary + with open(svg_tmp_name, "r") as svg_file: + doc = xmltodict.parse(svg_file.read()) + width = doc["svg"]["@width"] + if width.endswith("pt"): + width = float(width[:-2]) + if width > 600: + doc["svg"].pop("@height") + doc["svg"].pop("@width") + + doc["svg"]["@preserveAspectRatio"] = "xMinYMin meet" + + with open(svg_tmp_name, "w") as svg_file: + svg_file.write(xmltodict.unparse(doc)) + with open(svg_tmp_name, "r") as svg_file: django_file = File(svg_file) attr = "relation_image" + suffix diff --git a/requirements.txt b/requirements.txt index 720276f27..9f93e818b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ html5lib==0.999999999 pyqrcode==1.2.1 pypng==0.0.19 +xmltodict==0.10 requests==2.12 diff --git a/scss/custom.scss b/scss/custom.scss index ff595219d..3bb2a229f 100644 --- a/scss/custom.scss +++ b/scss/custom.scss @@ -651,6 +651,15 @@ ul.compact{ width: 200px; } +.svg-image{ + display: inline-block; + position: relative; + width: 100%; + vertical-align: middle; + text-align: center; + overflow: hidden; +} + .window-main-image { height: 300px; display: block; -- cgit v1.2.3