Commit c7c2f9b7 authored by Janez K's avatar Janez K

dodal word cloud widget

parent 7cda25b4
This diff is collapsed.
...@@ -140,4 +140,7 @@ def base_ravel_list(input_dict): ...@@ -140,4 +140,7 @@ def base_ravel_list(input_dict):
result = [] result = []
ravel(ilist, result) ravel(ilist, result)
return {'clean_list': result} return {'clean_list': result}
#end #end
\ No newline at end of file
def base_wordcloud(input_dict):
return {}
\ No newline at end of file
{% if iframe %}
<div id="vis"></div>
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery-1.7.1.min.js"></script>
<script src="{{STATIC_URL}}js/d3/d3-2.js"></script>
<script src="{{STATIC_URL}}js/d3/d3.layout.cloud.js"></script>
<script type="text/javascript">
var fill = d3.scale.category20b();
var w = 650,
h = 500;
var words = [],
max,
scale = 1,
complete = 0,
keyword = "",
tags,
fontSize,
maxLength = 30,
fetcher = "http://search.twitter.com/search.json?rpp=100&q={word}",
statusText = d3.select("#status");
var layout = d3.layout.cloud()
.timeInterval(10)
.size([w, h])
.fontSize(function(d) { return fontSize(+d.value); })
.text(function(d) { return d.key; })
//.on("word", progress)
.on("end", draw);
var svg = d3.select("#vis").append("svg")
.attr("width", w)
.attr("height", h);
var background = svg.append("g"),
vis = svg.append("g")
.attr("transform", "translate(" + [w >> 1, h >> 1] + ")");
// From Jonathan Feinberg's cue.language, see lib/cue.language/license.txt.
var stopWords = /^(i|me|my|myself|we|us|our|ours|ourselves|you|your|yours|yourself|yourselves|he|him|his|himself|she|her|hers|herself|it|its|itself|they|them|their|theirs|themselves|what|which|who|whom|whose|this|that|these|those|am|is|are|was|were|be|been|being|have|has|had|having|do|does|did|doing|will|would|should|can|could|ought|i'm|you're|he's|she's|it's|we're|they're|i've|you've|we've|they've|i'd|you'd|he'd|she'd|we'd|they'd|i'll|you'll|he'll|she'll|we'll|they'll|isn't|aren't|wasn't|weren't|hasn't|haven't|hadn't|doesn't|don't|didn't|won't|wouldn't|shan't|shouldn't|can't|cannot|couldn't|mustn't|let's|that's|who's|what's|here's|there's|when's|where's|why's|how's|a|an|the|and|but|if|or|because|as|until|while|of|at|by|for|with|about|against|between|into|through|during|before|after|above|below|to|from|up|upon|down|in|out|on|off|over|under|again|further|then|once|here|there|when|where|why|how|all|any|both|each|few|more|most|other|some|such|no|nor|not|only|own|same|so|than|too|very|say|says|said|shall)$/,
punctuation = /[!"&()*+,-\.\/:;<=>?\[\\\]^`\{|\}~]+/g,
wordSeparators = /[\s\u3031-\u3035\u309b\u309c\u30a0\u30fc\uff70]+/g,
discard = /^(@|https?:)/,
htmlTags = /(<[^>]*?>|<script.*?<\/script>|<style.*?<\/style>|<head.*?><\/head>)/g,
matchTwitter = /^https?:\/\/([^\.]*\.)?twitter\.com/;
function parseHTML(d) {
parseText(d.replace(htmlTags, " ").replace(/&#(x?)([\dA-Fa-f]{1,4});/g, function(d, hex, m) {
return String.fromCharCode(+((hex ? "0x" : "") + m));
}).replace(/&\w+;/g, " "));
}
function flatten(o, k) {
if (typeof o === "string") return o;
var text = [];
for (k in o) {
var v = flatten(o[k], k);
if (v) text.push(v);
}
return text.join(" ");
}
function parseText(text) {
tags = {};
var cases = {};
text.split(wordSeparators).forEach(function(word) {
if (discard.test(word)) return;
word = word.replace(punctuation, "");
if (stopWords.test(word.toLowerCase())) return;
word = word.substr(0, maxLength);
cases[word.toLowerCase()] = word;
tags[word = word.toLowerCase()] = (tags[word] || 0) + 1;
});
tags = d3.entries(tags).sort(function(a, b) { return b.value - a.value; });
tags.forEach(function(d) { d.key = cases[d.key]; });
generate();
}
function generate() {
layout
.font("Impact")
.spiral("archimedean");
fontSize = d3.scale["log"]().range([10, 100]);
if (tags.length) fontSize.domain([+tags[tags.length - 1].value || 1, +tags[0].value]);
complete = 0;
//statusText.style("display", null);
words = [];
layout.stop().words(tags.slice(0, max = Math.min(tags.length, 250))).start();
}
function draw(data, bounds) {
statusText.style("display", "none");
scale = bounds ? Math.min(
w / Math.abs(bounds[1].x - w / 2),
w / Math.abs(bounds[0].x - w / 2),
h / Math.abs(bounds[1].y - h / 2),
h / Math.abs(bounds[0].y - h / 2)) / 2 : 1;
words = data;
var text = vis.selectAll("text")
.data(words, function(d) { return d.text.toLowerCase(); });
text.transition()
.duration(1000)
.attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; })
.style("font-size", function(d) { return d.size + "px"; });
text.enter().append("text")
.attr("text-anchor", "middle")
.attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; })
.style("font-size", function(d) { return d.size + "px"; })
.style("opacity", 1e-6)
.transition()
.duration(1000)
.style("opacity", 1);
text.style("font-family", function(d) { return d.font; })
.style("fill", function(d) { return fill(d.text.toLowerCase()); })
.text(function(d) { return d.text; });
var exitGroup = background.append("g")
.attr("transform", vis.attr("transform"));
var exitGroupNode = exitGroup.node();
text.exit().each(function() {
exitGroupNode.appendChild(this);
});
exitGroup.transition()
.duration(1000)
.style("opacity", 1e-6)
.remove();
vis.transition()
.delay(1000)
.duration(750)
.attr("transform", "translate(" + [w >> 1, h >> 1] + ")scale(" + scale + ")");
}
(function() {
var r = 40.5,
px = 35,
py = 20;
var angles = d3.select("#angles").append("svg")
.attr("width", 2 * (r + px))
.attr("height", r + 1.5 * py)
.append("g")
.attr("transform", "translate(" + [r + px, r + py] +")");
angles.append("path")
.style("fill", "none")
.attr("d", ["M", -r, 0, "A", r, r, 0, 0, 1, r, 0].join(" "));
angles.append("line")
.attr("x1", -r - 7)
.attr("x2", r + 7);
angles.append("line")
.attr("y2", -r - 7);
angles.selectAll("text")
.data([-90, 0, 90])
.enter().append("text")
.attr("dy", function(d, i) { return i === 1 ? null : ".3em"; })
.attr("text-anchor", function(d, i) { return ["end", "middle", "start"][i]; })
.attr("transform", function(d) {
d += 90;
return "rotate(" + d + ")translate(" + -(r + 10) + ")rotate(" + -d + ")translate(2)";
})
.text(function(d) { return d + "°"; });
var radians = Math.PI / 180,
from,
to,
count,
scale = d3.scale.linear(),
arc = d3.svg.arc()
.innerRadius(0)
.outerRadius(r);
getAngles();
function getAngles() {
count = 5;
from = Math.max(-90, Math.min(90, -60));
to = Math.max(-90, Math.min(90, 60));
update();
}
function update() {
scale.domain([0, count - 1]).range([from, to]);
var step = (to - from) / count;
var path = angles.selectAll("path.angle")
.data([{startAngle: from * radians, endAngle: to * radians}]);
path.enter().insert("path", "circle")
.attr("class", "angle")
.style("fill", "#fc0");
path.attr("d", arc);
var line = angles.selectAll("line.angle")
.data(d3.range(count).map(scale));
line.enter().append("line")
.attr("class", "angle");
line.exit().remove();
line.attr("transform", function(d) { return "rotate(" + (90 + d) + ")"; })
.attr("x2", function(d, i) { return !i || i === count - 1 ? -r - 5 : -r; });
var drag = angles.selectAll("path.drag")
.data([from, to]);
drag.enter().append("path")
.attr("class", "drag")
.attr("d", "M-9.5,0L-3,3.5L-3,-3.5Z")
.call(d3.behavior.drag()
.on("drag", function(d, i) {
d = (i ? to : from) + 90;
var start = [-r * Math.cos(d * radians), -r * Math.sin(d * radians)],
m = [d3.event.x, d3.event.y],
delta = ~~(Math.atan2(cross(start, m), dot(start, m)) / radians);
d = Math.max(-90, Math.min(90, d + delta - 90)); // remove this for 360°
delta = to - from;
if (i) {
to = d;
if (delta > 360) from += delta - 360;
else if (delta < 0) from = to;
} else {
from = d;
if (delta > 360) to += 360 - delta;
else if (delta < 0) to = from;
}
update();
})
.on("dragend", generate));
drag.attr("transform", function(d) { return "rotate(" + (d + 90) + ")translate(-" + r + ")"; });
layout.rotate(function() {
return scale(~~(Math.random() * count));
});
}
function cross(a, b) { return a[0] * b[1] - a[1] * b[0]; }
function dot(a, b) { return a[0] * b[0] + a[1] * b[1]; }
})();
updateCloud = function () {
$.get("{{request.get_full_path}}?raw=1",function(html) {
parseHTML(html);
},"html")
};
updateCloud();
</script>
{% else %}
<div id="widgetvisualization-{{widget.pk}}" rel="{{widget.pk}}" class="widgetvisualizationdialog" title="{{widget.name}} visualization" width="750px" height="700px">
<iframe src="./widget-iframe/{{widget.pk}}/" width="700px" height="550px">
</div>
{% endif %}
\ No newline at end of file
from django.shortcuts import render
def base_wordcloud(request,input_dict,output_dict,widget,iframe=False):
if request.GET.get('raw',None)=="1":
return render(request, 'visualizations/base_wordcloud_raw.html',{'string':input_dict['string']})
return render(request, 'visualizations/base_wordcloud.html',{'widget':widget,'input_dict':input_dict,'output_dict':output_dict,'iframe':iframe})
\ No newline at end of file
...@@ -39,6 +39,7 @@ urlpatterns += patterns('', ...@@ -39,6 +39,7 @@ urlpatterns += patterns('',
url(r'^run-widget/', 'workflows.views.run_widget', name='run widget'), url(r'^run-widget/', 'workflows.views.run_widget', name='run widget'),
url(r'^widget-results/', 'workflows.views.widget_results', name='widget results'), url(r'^widget-results/', 'workflows.views.widget_results', name='widget results'),
url(r'^widget-visualization/', 'workflows.views.visualize_widget', name='widget visualization'), url(r'^widget-visualization/', 'workflows.views.visualize_widget', name='widget visualization'),
url(r'^widget-iframe/(?P<widget_id>[0-9]+)/$', 'workflows.views.widget_iframe', name='widget iframe'),
url(r'^get-unfinished/', 'workflows.views.get_unfinished', name='get unfinished'), url(r'^get-unfinished/', 'workflows.views.get_unfinished', name='get unfinished'),
url(r'^upload-handler/$', 'workflows.views.upload_handler', name='file upload'), url(r'^upload-handler/$', 'workflows.views.upload_handler', name='file upload'),
url(r'^widget-interaction/', 'workflows.views.widget_interaction', name='widget interaction'), url(r'^widget-interaction/', 'workflows.views.widget_interaction', name='widget interaction'),
......
...@@ -1317,3 +1317,32 @@ def export_package(request, packages): ...@@ -1317,3 +1317,32 @@ def export_package(request, packages):
response = HttpResponse(mimetype='text/plain',content=content) response = HttpResponse(mimetype='text/plain',content=content)
return response return response
@login_required
def widget_iframe(request, widget_id):
w = get_object_or_404(Widget, pk=widget_id)
if (w.workflow.user==request.user):
output_dict = {}
for o in w.outputs.all():
output_dict[o.variable]=o.value
input_dict = {}
for i in w.inputs.all():
if not i.parameter:
if i.connections.count() > 0:
i.value = i.connections.all()[0].output.value
i.save()
else:
i.value = None
i.save()
if i.multi_id == 0:
input_dict[i.variable]=i.value
else:
if not i.variable in input_dict:
input_dict[i.variable]=[]
if not i.value == None:
input_dict[i.variable].append(i.value)
view_to_call = getattr(workflows.visualization_views,w.abstract_widget.visualization_view)
return view_to_call(request, input_dict, output_dict, w, True)
else:
return HttpResponse(status=400)
return HttpResponse("OK")
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment