Skip to content

Commit 4b8d459

Browse files
author
Dennis Schwartz
committed
Update visualizations template to work for built components
1 parent 7e6caa3 commit 4b8d459

File tree

4 files changed

+216
-92
lines changed

4 files changed

+216
-92
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.11.15 on 2018-11-15 15:09
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('main', '0018_auto_20180802_1019'),
12+
]
13+
14+
operations = [
15+
migrations.AlterField(
16+
model_name='component',
17+
name='tags',
18+
field=models.ManyToManyField(to='main.Tag'),
19+
),
20+
]

main/serializers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ class SniperDataSerializer(serializers.ModelSerializer):
123123

124124
class Meta:
125125
model = SniperData
126-
fields = ('wzrd_url',)
127-
126+
fields = ('wzrd_url', 'no_browserify',)
127+
128128
class SnippetSerializer(serializers.ModelSerializer):
129129

130130
class Meta:

main/templates/main/visualizations.html

Lines changed: 162 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,176 @@
22
Template for rendering visualizations.
33

44
1. Obtain visualization for iframe with URL /visualization/<url_name>/<visualization_name>/
5-
2. For dependencies
6-
(% for dependency in js_dependencies %) // Similarly for css dependencies
7-
URL = dependency.js_url
8-
{% endfor %}
9-
3. Snippet raw git URL : {{snippet.url}}
10-
4. Snippet name : {{snippet.name}}
11-
5. wzrd_url : {{sniper_data.wzrd_url}}
12-
6. no_browserify : {{sniper_data.no_browserify}}
13-
{% endcomment %}
14-
15-
<!DOCTYPE html>
16-
<html>
17-
<head>
18-
<meta charset="UTF-8">
19-
{% for dependency in css_dependencies %}
20-
<link rel="stylesheet" type="text/css" href="{{dependency.css_url}}" />
5+
2. For dependencies
6+
(% for dependency in js_dependencies %) // Similarly for css dependencies
7+
URL = dependency.js_url
218
{% endfor %}
22-
{% for dependency in js_dependencies %}
23-
<script type="application/x-javascript" src="{{dependency.js_url}}"></script>
24-
{% endfor %}
25-
<script type="application/x-javascript" src="{{sniper_data.wzrd_url}}@{{component.version}}"></script>
26-
</head>
27-
<body>
28-
<div id="placeholderDiv" style="display: none">
29-
{{snippet_script}}
30-
</div>
31-
</div>
32-
<div id='snippetDiv'></div>
33-
</body>
34-
<script type="text/javascript">
35-
const replaceAll = function(str, search, replacement) {
36-
return str.replace(new RegExp(search, 'g'), replacement);
37-
};
38-
39-
// find main element variable
40-
findMainVar = function(content) {
41-
var tags = ["yourDiv", "mainDiv", "rootDiv", "masterDiv", "biojsDiv"];
42-
var defaultDiv = tags[0];
43-
tags.forEach(function(tag) {
44-
if (content.indexOf(tag) >= 0) {
45-
defaultDiv = tag;
9+
3. Snippet raw git URL : {{snippet.url}}
10+
4. Snippet name : {{snippet.name}}
11+
5. wzrd_url : {{sniper_data.wzrd_url}}
12+
6. no_browserify : {{sniper_data.no_browserify}}
13+
{% endcomment %}
14+
15+
<!DOCTYPE html>
16+
<html>
17+
18+
<head>
19+
<meta charset="UTF-8">
20+
<style>
21+
body {
22+
min-height: 60px;
23+
}
24+
25+
.message {
26+
height: 60px;
27+
color: black;
28+
display: none;
29+
}
30+
31+
#loading-bar-spinner.spinner {
32+
left: 50%;
33+
margin-left: -20px;
34+
top: 50%;
35+
margin-top: -20px;
36+
position: absolute;
37+
z-index: 19 !important;
38+
animation: loading-bar-spinner 400ms linear infinite;
39+
}
40+
41+
#loading-bar-spinner.spinner .spinner-icon {
42+
width: 60px;
43+
height: 60px;
44+
border: solid 4px transparent;
45+
border-top-color: rgb(0, 126, 58) !important;
46+
border-left-color: rgb(0, 126, 58) !important;
47+
border-radius: 50%;
4648
}
47-
});
48-
return defaultDiv;
49-
};
50-
51-
// translate relative paths
52-
translateRelative = function(body, baseLocal, path) {
53-
if (body.indexOf("./") >= 0) {
54-
var htmlUrl = baseLocal + "/" + path + "/";
55-
body = body.replace(/\.\.\//g, baseLocal + "/");
56-
body = body.replace(/\.\//g, htmlUrl);
49+
50+
@keyframes loading-bar-spinner {
51+
0% { transform: rotate(0deg); transform: rotate(0deg); }
52+
100% { transform: rotate(360deg); transform: rotate(360deg); }
53+
}
54+
55+
</style>
56+
</head>
57+
<body>
58+
<div id="loading-bar-spinner" class="spinner">
59+
<div class="spinner-icon"></div>
60+
</div>
61+
<p class="message">
62+
This visualisation can currently not be displayed due to its reliance on local dependencies!<br>
63+
Please contact the developer to update it's package.json or refer to the update guide here:
64+
>insert_link<
65+
</p>
66+
<div id='snippetDiv'></div>
67+
</body>
68+
<script type="text/javascript">
69+
function stopLoading() {
70+
const spinner = document.getElementById('loading-bar-spinner');
71+
spinner.style.display = 'none';
5772
}
58-
return body;
59-
};
73+
const componentJSON = '{{component|escapejs}}';
74+
const component = JSON.parse(componentJSON);
75+
const noBrowserify = '{{no_browserify|escapejs}}';
76+
if (noBrowserify === 'False') {
77+
stopLoading();
78+
const message = document.getElementsByClassName('message')[0];
79+
message.style.display = 'block';
80+
}
81+
82+
const jsDepsStr = '{{ js_dependencies | escapejs }}';
83+
const cssDepsStr = '{{ css_dependencies | escapejs }}';
84+
const jsDeps = JSON.parse(jsDepsStr);
85+
const cssDeps = JSON.parse(cssDepsStr);
86+
const script = '{{ snippet_script | escapejs }}'
87+
88+
Promise.all(cssDeps.map(css => {
89+
return new Promise((res, rej) => {
90+
const style = document.createElement('link');
91+
style.rel = 'stylesheet';
92+
style.type = 'text/css';
93+
style.href = css.fields.css_url;
94+
style.onload = res;
95+
document.head.appendChild(style);
96+
});
97+
})).then(() => {
98+
console.log('done loading css!');
99+
return Promise.all(jsDeps.map(js => {
100+
return new Promise((res, rej) => {
101+
const script = document.createElement("script");
102+
script.setAttribute('src', js.fields.js_url);
103+
script.onload = res;
104+
document.head.appendChild(script);
105+
});
106+
})).then(() => {
107+
console.log('done loading js!');
108+
})
109+
})
110+
.then(() => {
111+
stopLoading();
112+
var rootDiv = document.getElementById('snippetDiv');
113+
eval(script);
114+
});
115+
116+
// const plugin = document.createElement("script");
117+
// plugin.setAttribute(
118+
// 'src',
119+
// 'https://github.com/DennisSchwartz/mplexviz-ngraph/releases/download/v1.0.2/bundle.js'
120+
// );
121+
// plugin.onload = this.createVisualisation;
122+
// // plugin.async = false;
123+
// document.head.appendChild(plugin);
124+
// const replaceAll = function (str, search, replacement) {
125+
// return str.replace(new RegExp(search, 'g'), replacement);
126+
// };
127+
128+
// // find main element variable
129+
// findMainVar = function (content) {
130+
// var tags = ["yourDiv", "mainDiv", "rootDiv", "masterDiv", "biojsDiv"];
131+
// var defaultDiv = tags[0];
132+
// tags.forEach(function (tag) {
133+
// if (content.indexOf(tag) >= 0) {
134+
// defaultDiv = tag;
135+
// }
136+
// });
137+
// return defaultDiv;
138+
// };
139+
140+
// // translate relative paths
141+
// translateRelative = function (body, baseLocal, path) {
142+
// if (body.indexOf("./") >= 0) {
143+
// var htmlUrl = baseLocal + "/" + path + "/";
144+
// body = body.replace(/\.\.\//g, baseLocal + "/");
145+
// body = body.replace(/\.\//g, htmlUrl);
146+
// }
147+
// return body;
148+
// };
60149

61150

62-
var script = document.getElementById("placeholderDiv").innerHTML;
63-
script = replaceAll(script, "&lt;", "<");
64-
script = replaceAll(script, "&gt;", ">");
151+
// var script = document.getElementById("placeholderDiv").innerHTML;
152+
// script = replaceAll(script, "&lt;", "<");
153+
// script = replaceAll(script, "&gt;", ">");
65154

66-
var githubURL = "{{component.github_url}}";
67-
var lastCommitHash = "{{component.latest_commit_hash}}";
155+
// var githubURL = "{{component.github_url}}";
156+
// var lastCommitHash = "{{component.latest_commit_hash}}";
68157

69-
var div = findMainVar(script);
70-
var mainDiv = "var "+div+" = document.getElementById('snippetDiv');"
158+
// var div = findMainVar(script);
159+
// var mainDiv = "var " + div + " = document.getElementById('snippetDiv');"
71160

72-
// get rawgit base URL
73-
var rawgitURL = githubURL.replace("github.com", "cdn.rawgit.com");
74-
if(rawgitURL.substr(rawgitURL.length - 1) === '/') {
75-
rawgitURL = rawgitURL + '' + lastCommitHash;
76-
} else {
77-
rawgitURL = rawgitURL + '/' + lastCommitHash;
78-
}
161+
// // get rawgit base URL
162+
// var rawgitURL = githubURL.replace("github.com", "cdn.rawgit.com");
163+
// if (rawgitURL.substr(rawgitURL.length - 1) === '/') {
164+
// rawgitURL = rawgitURL + '' + lastCommitHash;
165+
// } else {
166+
// rawgitURL = rawgitURL + '/' + lastCommitHash;
167+
// }
79168

80-
// change relative paths in script
81-
script = translateRelative(script, rawgitURL, "snippets");
169+
// // change relative paths in script
170+
// script = translateRelative(script, rawgitURL, "snippets");
82171

83-
// complete script and evaluate the script
84-
script = mainDiv + script;
85-
eval(script);
172+
// // complete script and evaluate the script
173+
// script = mainDiv + script;
174+
// eval(script);
175+
</script>
86176

87-
</script>
88-
</html>
177+
</html>

main/views.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from django.shortcuts import render
22
from .serializers import *
3-
from django.http import JsonResponse
3+
from rest_framework.renderers import JSONRenderer
4+
from management.commands.updatecomponents import send_GET_request
5+
from django.http import JsonResponse, HttpResponseServerError
46
from django.contrib.admin.views.decorators import staff_member_required
57
from django.http import HttpResponse
68
import urllib, json
79
from django.core.management import call_command
8-
from django.core.serializers.json import DjangoJSONEncoder
10+
from django.core.serializers import serialize
11+
from django.views.decorators.clickjacking import xframe_options_exempt
912
import numpy as np
1013

1114
def index(request):
@@ -60,22 +63,34 @@ def component_details(request, url_name):
6063
'css_dependencies' : css_dependencies.data,
6164
})
6265

66+
@xframe_options_exempt
6367
def render_visualization(request, url_name, visualization_name):
64-
component = Component.objects.get(url_name=url_name)
65-
js_dependencies = component.jsdependency_set.all()
66-
css_dependencies = component.cssdependency_set.all()
67-
sniper_data = component.sniperdata
68-
snippet = Snippet.objects.get(sniperData=sniper_data, name=visualization_name)
69-
data = urllib.urlopen(snippet.url).read()
70-
context = {
71-
'component' : DetailComponentSerializer(component).data,
72-
'js_dependencies' : js_dependencies,
73-
'css_dependencies' : css_dependencies,
74-
'snippet' : snippet,
75-
'snippet_script' : data,
76-
'sniper_data' : sniper_data,
77-
}
78-
return render(request, 'main/visualizations.html', context)
68+
try:
69+
component = Component.objects.get(url_name=url_name)
70+
js_dependencies = component.jsdependency_set.all()
71+
css_dependencies = component.cssdependency_set.all()
72+
sniper_data = component.sniperdata
73+
snippet = Snippet.objects.get(sniperData=sniper_data, name=visualization_name)
74+
response = send_GET_request(snippet.url)
75+
script = response.read()
76+
serializer = DetailComponentSerializer(component).data
77+
component_data = JSONRenderer().render(serializer)
78+
js_deps_json = serialize('json', js_dependencies)
79+
css_deps_json = serialize('json', css_dependencies)
80+
context = {
81+
'component' : component_data,
82+
'js_dependencies' : js_deps_json,
83+
'css_dependencies' : css_deps_json,
84+
'snippet' : snippet,
85+
'snippet_script' : script,
86+
'sniper_data' : sniper_data,
87+
'no_browserify': sniper_data.no_browserify
88+
}
89+
# return HttpResponse()
90+
return render(request, 'main/visualizations.html', context)
91+
except Exception as e:
92+
print('Error in visualisation!', e)
93+
return HttpResponseServerError(e)
7994

8095
@staff_member_required
8196
def update_data(request):

0 commit comments

Comments
 (0)