Coupure prévue mardi 3 Août au matin pour maintenance du serveur. Nous faisons au mieux pour que celle-ci soit la plus brève possible.

Commit 7b45b9eb authored by matjaz's avatar matjaz
Browse files

Merge remote-tracking branch 'remotes/origin/dev' into dev_latino

Conflicts:
	workflows/library.py
	workflows/visualization_views.py
parents b1a1f033 01bd5979
def test(input_dict):
print 'great success'
return input_dict
\ No newline at end of file
'''
Decision support interaction views.
'''
from django.shortcuts import render
def kepner_tregoe(request, input_dict, output_dict, widget):
attributes = [att.name for att in input_dict['data'].domain.features]
return render(request, 'interactions/kepner_tregoe.html', {'widget':widget, 'attributes':attributes})
'''
Decision support library functions.
'''
def kepner_tregoe(input_dict):
output_dict = input_dict
output_dict['model'] = None
return output_dict
class KepnerTregoe:
'''
Kepner-Tregoe model.
'''
def __init__(self, data, weights, smaller_is_better=None):
self.data = data
self.weights = weights
self.smaller_is_better = smaller_is_better if smaller_is_better else set()
self.name = 'Kepner-Tregoe'
def __call__(self, weights=None):
import Orange
from Orange.feature import Type
if weights == None:
weights = self.weights
# New augmented table
norm_data = Orange.data.Table(self.data)
newid = min(norm_data.domain.get_metas().keys()) - 1
score_attr = Orange.feature.Continuous('score')
norm_data.domain.add_meta(newid, score_attr)
norm_data.add_meta_attribute(score_attr)
# Normalize the attributes column-wise
for att in norm_data.domain:
if att.var_type == Type.Continuous:
col = [ex[att] for ex in norm_data]
col_norm = float(sum(col))
for ex in norm_data:
if att.var_type == Type.Continuous:
ex[att] = ex[att] / col_norm
# Use the inverse of an attr. value if smaller values should be treated as 'better'.
inverse = lambda x, att: 1-x if att in self.smaller_is_better else x
for ex in norm_data:
score = sum([inverse(ex[att], att.name) * weights.get(att.name, 1) for att in norm_data.domain.features if att.var_type == Type.Continuous])
ex['score'] = score
return norm_data
def kepner_tregoe_finished(postdata, input_dict, output_dict):
# Fetch the data and the weights from the form.
data = input_dict['data']
attributes = [att.name for att in data.domain.features]
weights = {}
widget_id = postdata['widget_id'][0]
smaller_is_better = set()
for att in attributes:
weights[att]=int(postdata['weight'+str(widget_id)+str(att)][0])
if postdata.has_key('smallerIsBetter'+str(widget_id)+str(att)):
smaller_is_better.add(att)
# Instantiate a KepnerTregoe model.
kt = KepnerTregoe(data, weights, smaller_is_better=smaller_is_better)
output_dict = {}
output_dict['data'] = kt()
output_dict['model'] = kt
return output_dict
def sensitivity_analysis(input_dict):
return input_dict
def ds_charts(input_dict):
return input_dict
'''
Decision support visualization views.
'''
from django.shortcuts import render
import json
def sensitivity_analysis_viewer(request, input_dict, output_dict, widget):
'''
Computes the sensitivity analysis graph.
@author: Anze Vavpeltic, 2012
'''
model = input_dict['model']
attributes = [att.name for att in input_dict['model'].data.domain.features]
data_points = {}
domain = range(0, 101, 10)
# Compute for each attribute
for target_att in attributes:
y, ex_data = [], {}
# For collecting scores for each example across different weights
for ex in model.data:
ex_data[ex['label'].value] = []
# Compute the scores for each weight
for w in domain:
model.weights[target_att] = w
ds = model()
for ex in ds:
ex_data[ex['label'].value].append([w, ex['score'].value])
for ex in model.data:
y.append({'name' : ex['label'].value, 'data' : ex_data[ex['label'].value]})
data_points[target_att] = y
return render(request, 'visualizations/sensitivity_analysis.html',
{'widget' : widget,
'attributes': attributes,
'data_points' : json.dumps(data_points),
'output_dict': {}
})
def ds_charts_viewer(request, input_dict, output_dict, widget):
'''
Decision support visualization.
@author: Anze Vavpeltic, 2012
'''
model = input_dict['model']
norm_data = model()
weight_shares = [ [att, weight] for att, weight in model.weights.items() ]
attributes = sorted(model.weights.keys())
alternatives = [ex['label'].value for ex in norm_data]
weights_bar = [{ 'data' : [model.weights[att] for att in attributes] }]
values_column = [{ 'data' : [ex['score'].value for ex in norm_data] }]
alt_data = [{ 'name' : ex['label'].value, 'data' : [ex[att].value for att in attributes] } for ex in norm_data ]
return render(request, 'visualizations/ds_charts.html',
{'widget' : widget,
'model_name' : model.name,
'attributes' : json.dumps(attributes),
'alternatives' : json.dumps(alternatives),
'weight_shares' : json.dumps(weight_shares),
'weights_bar' : json.dumps(weights_bar),
'values_column' : json.dumps(values_column),
'alt_data' : json.dumps(alt_data)
})
from django.shortcuts import render
from decision_support.interaction import *
def test_interaction(request,input_dict,output_dict,widget):
return render(request, 'interactions/test_interaction.html',{'widget':widget})
......@@ -79,6 +80,7 @@ def build_subgroups(request, input_dict, output_dict, widget):
return render(request, 'interactions/build_subgroups.html', {'widget':widget, 'data':data, 'target':target})
def kepner_tregoe(request, input_dict, output_dict, widget):
attributes = [att.name for att in input_dict['data'].domain.features]
return render(request, 'interactions/kepner_tregoe.html', {'widget':widget, 'attributes':attributes})
def alter_table(request, input_dict, output_dict, widget):
from visualization_views import orng_table_to_dict
data = input_dict['data']
return render(request, 'interactions/alter_table.html', {'widget' : widget,'input_dict' : input_dict,'output_dict' : orng_table_to_dict(data)})
from workflows.security import safeOpen
import nlp
import cPickle
import json
from decision_support.library import *
def test_interaction(input_dict):
return input_dict
......@@ -838,73 +840,35 @@ def load_corpus(input_dict):
response = ws.client.parseFile(fileName=fname, inFile=data)
return {'corpus' : response['parsedFile']}
def kepner_tregoe(input_dict):
output_dict = input_dict
output_dict['model'] = None
return output_dict
class KepnerTregoe:
'''
Kepner Tregoe model.
'''
def __init__(self, data, weights, smaller_is_better=None):
self.data = data
self.weights = weights
self.smaller_is_better = smaller_is_better if smaller_is_better else set()
self.name = 'Kepner-Tregoe'
def __call__(self, weights=None):
import Orange
from Orange.feature import Type
if weights == None:
weights = self.weights
# New augmented table
norm_data = Orange.data.Table(self.data)
newid = min(norm_data.domain.get_metas().keys()) - 1
score_attr = Orange.feature.Continuous('score')
norm_data.domain.add_meta(newid, score_attr)
norm_data.add_meta_attribute(score_attr)
# Normalize the attributes column-wise
for att in norm_data.domain:
if att.var_type == Type.Continuous:
col = [ex[att] for ex in norm_data]
col_norm = float(sum(col))
for ex in norm_data:
if att.var_type == Type.Continuous:
ex[att] = ex[att] / col_norm
# Use the inverse of an attr. value if smaller values should be treated as 'better'.
inverse = lambda x, att: 1-x if att in self.smaller_is_better else x
for ex in norm_data:
score = sum([inverse(ex[att], att.name) * weights.get(att.name, 1) for att in norm_data.domain.features if att.var_type == Type.Continuous])
ex['score'] = score
return norm_data
def kepner_tregoe_finished(postdata, input_dict, output_dict):
# Fetch the data and the weights from the form.
data = input_dict['data']
attributes = [att.name for att in data.domain.features]
weights = {}
widget_id = postdata['widget_id'][0]
smaller_is_better = set()
for att in attributes:
weights[att]=int(postdata['weight'+str(widget_id)+str(att)][0])
if postdata.has_key('smallerIsBetter'+str(widget_id)+str(att)):
smaller_is_better.add(att)
# Instantiate a KepnerTregoe model.
kt = KepnerTregoe(data, weights, smaller_is_better=smaller_is_better)
output_dict = {}
output_dict['data'] = kt()
output_dict['model'] = kt
return output_dict
def sensitivity_analysis(input_dict):
return input_dict
def ds_charts(input_dict):
return input_dict
def string_to_file(input_dict):
return {}
def alter_table(input_dict):
return {'altered_data' : None}
def alter_table_finished(postdata, input_dict, output_dict):
import Orange
from Orange.feature import Type
from visualization_views import orng_table_to_dict
widget_id = postdata['widget_id'][0]
# Parse the changes
altered_cells = json.loads(postdata['alteredCells'+widget_id][0])
new_table = Orange.data.Table(input_dict['data'])
for cell, new_value in altered_cells.items():
tokens = cell.split('_')
inst_idx, att = int(tokens[1]), str(tokens[2])
if new_table[inst_idx][att].var_type == Type.Continuous:
new_table[inst_idx][att] = float(new_value)
else: # Discrete or string
# TODO:
# This raises an exception if new_value is not among the legal values for the discrete attribute
# - add a dropdown list of legal values when editing the table!
try:
new_table[inst_idx][att] = str(new_value)
except: # Catch orange exception and give a proper error message.
raise Exception("Illegal value '%s' for discrete attribute '%s', legal values are: %s." % (new_value, att, new_table.domain[att].values))
return {'altered_data' : new_table}
#------------------------------------------------------------------------------
# LATINO INTERFACE
#------------------------------------------------------------------------------
......
......@@ -439,9 +439,7 @@ class Widget(models.Model):
self.finished=False
self.save()
raise
print outputs
for o in self.outputs.all():
print o
if not self.abstract_widget is None:
o.value = outputs[o.variable]
o.save()
......
......@@ -226,4 +226,10 @@ html[xmlns] .dataTables_wrapper {
}
* html .dataTables_wrapper {
height: 1%;
}
\ No newline at end of file
}
.ui-widget input {
margin-bottom: 0px;
}
.dataTables_filter input {
margin-bottom: 5px;
}
(function($){$.fn.editable=function(target,options){if('disable'==target){$(this).data('disabled.editable',true);return;}
if('enable'==target){$(this).data('disabled.editable',false);return;}
if('destroy'==target){$(this).unbind($(this).data('event.editable')).removeData('disabled.editable').removeData('event.editable');return;}
var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr('title',settings.tooltip);}
settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data('event.editable',settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder);}
$(this).bind(settings.event,function(e){if(true===$(this).data('disabled.editable')){return;}
if(self.editing){return;}
if(false===onedit.apply(this,[settings,self])){return;}
e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr('title');}
if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;}
if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}}
if($(this).html().toLowerCase().replace(/(;|")/g,'')==settings.placeholder.toLowerCase().replace(/(;|")/g,'')){$(this).html('');}
self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('<form />');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}}
if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}}
var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);}
$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;}
content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();}
input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit();},200);});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});}
form.submit(function(e){if(t){clearTimeout(t);}
e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);}
if('PUT'==settings.method){submitdata['_method']='put';}
$(self).html(settings.indicator);var ajaxoptions={type:'POST',data:submitdata,dataType:'html',url:settings.target,success:function(result,status){if(ajaxoptions.dataType=='html'){$(self).html(result);}
self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr]);}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions);}}}
$(self).attr('title',settings.tooltip);return false;});});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);}
if(settings.tooltip){$(self).attr('title',settings.tooltip);}}}};});};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden"></input>');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset(this);},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('<button type="submit" />');submit.html(settings.submit);}
$(this).append(submit);}
if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('<button type="cancel" />');cancel.html(settings.cancel);}
$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;}
reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('<input />');if(settings.width!='none'){input.width(settings.width);}
if(settings.height!='none'){input.height(settings.height);}
input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('<textarea />');if(settings.rows){textarea.attr('rows',settings.rows);}else if(settings.height!="none"){textarea.height(settings.height);}
if(settings.cols){textarea.attr('cols',settings.cols);}else if(settings.width!="none"){textarea.width(settings.width);}
$(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('<select />');$(this).append(select);return(select);},content:function(data,settings,original){if(String==data.constructor){eval('var json = '+data);}else{var json=data;}
for(var key in json){if(!json.hasOwnProperty(key)){continue;}
if('selected'==key){continue;}
var option=$('<option />').val(key).append(json[key]);$('select',this).append(option);}
$('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==$.trim(original.revert)){$(this).attr('selected','selected');}});}}},addInputType:function(name,input){$.editable.types[name]=input;}};$.fn.editable.defaults={name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click.editable',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{},ajaxoptions:{}};})(jQuery);
\ No newline at end of file
......@@ -30,6 +30,7 @@
<script src="{{ STATIC_URL }}js/jquery.treeview.edit.js" type="text/javascript"></script>
<script src="{{ STATIC_URL }}js/jquery.jstree.js" type="text/javascript"></script>
<script src="{{ STATIC_URL }}js/jquery.dataTables.min.js" type="text/javascript"></script>
<script src="{{ STATIC_URL }}js/jquery.jeditable.mini.js" type="text/javascript"></script>
<!-- <script type="text/javascript" src="{{ STATIC_URL }}js/graphics.js"></script>-->
<script type="text/javascript" src="{{ STATIC_URL }}js/fileuploader.js"></script>
<script src="{{ STATIC_URL }}js/jquery.contextmenu.js" type="text/javascript"></script>
......
<div id="widgetinteract-{{widget.pk}}" rel="{{widget.pk}}" class="widgetinteractdialog" title="{{widget.name}} interaction" width="700" height="500">
<center>
<table cellpadding="0" cellspacing="0" border="0" class="display" id="datasetTable{{widget.pk}}">
<!-- header -->
<thead>
<tr>
{% for att in output_dict.attrs %}
<th>{{att}}</th>
{% endfor %}
{% if output_dict.class_var %}
<th>{{output_dict.class_var}} [class]</th>
{% endif %}
{% for att in output_dict.metas %}
<th>{{att}} [meta]</th>
{% endfor %}
</tr>
</thead>
<tbody>
<!-- instances -->
{% for inst in output_dict.data %}
<tr>
{% for att, v in inst %}
<td id="cell_{{forloop.parentloop.counter0}}_{{att}}">{{v}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<form>
<input type="hidden" name="alteredCells{{widget.pk}}" id="alteredCells{{widget.pk}}" value=""/>
<input type="hidden" name="widget_id" value="{{widget.pk}}"/>
</form>
</center>
<script type="text/javascript">
$(function () {
$(document).ready(function() {
var alteredCells = {};
$('#alteredCells{{widget.pk}}').val(JSON.stringify(alteredCells));
var oTable = $('#datasetTable{{widget.pk}}').dataTable( {
"bSortCellsTop" : true,
"bJQueryUI": true,
"sPaginationType": "full_numbers"
});
oTable.$('td').editable(function(value, settings) {
// Update the hidden input value
var id = $(this).attr("id");
// Update the value
alteredCells[id] = value;
$('#alteredCells{{widget.pk}}').val(JSON.stringify(alteredCells));
// On edit just return the new value (no need to make a server call).
return value;
}, {
width: '100%'
});
});
});
</script>
</div>
\ No newline at end of file
......@@ -19,7 +19,7 @@
<!-- instances -->
{% for inst in output_dict.data %}
<tr>
{% for v in inst %}
{% for _, v in inst %}
<td>{{v}}</td>
{% endfor %}
</tr>
......
from django.shortcuts import render
from django.http import Http404, HttpResponse
import nlp
import json
from decision_support.visualization import *
def odt_to_tab(request,input_dict,output_dict,widget):
import Orange
......@@ -55,42 +55,34 @@ def object_viewer(request,input_dict,output_dict,widget):
import pprint
output_dict = {'object_string':pprint.pformat(input_dict['object'])}
return render(request, 'visualizations/object_viewer.html',{'widget':widget,'input_dict':input_dict,'output_dict':output_dict})
def table_viewer(request,input_dict,output_dict,widget):
import Orange
data = input_dict['data']
attrs = []
metas = []
data_new = []
def orng_table_to_dict(data):
import Orange
attrs, metas, data_new = [], [], []
try:
class_var = data.domain.class_var.name
except:
class_var = ''
for m in data.domain.get_metas():
metas.append(data.domain.get_meta(m).name)
for a in data.domain.attributes:
attrs.append(a.name)
pretty_float = lambda x, a: '%.3f' % x if a.var_type == Orange.feature.Type.Continuous else x
for inst in xrange(len(data)):
inst_new = []
for a in data.domain.variables:
value = data[inst][a.name].value
inst_new.append(pretty_float(value, a))
inst_new.append((a.name, pretty_float(value, a)))
for m in data.domain.get_metas():
value = data[inst][m].value
a = data.domain.get_meta(m)
inst_new.append(pretty_float(value, a))
inst_new.append((a.name, pretty_float(value, a)))
data_new.append(inst_new)
return {'attrs':attrs, 'metas':metas, 'data':data_new, 'class_var':class_var}
output_dict = {'attrs':attrs, 'metas':metas, 'data':data_new, 'class_var':class_var}
return render(request, 'visualizations/table_viewer.html',{'widget':widget,'input_dict':input_dict,'output_dict':output_dict})
def table_viewer(request,input_dict,output_dict,widget):
data = input_dict['data']
return render(request, 'visualizations/table_viewer.html',{'widget':widget,'input_dict':input_dict,'output_dict':orng_table_to_dict(data)})
def pr_space_view(request,input_dict,output_dict,widget):
return render(request, 'visualizations/pr_space.html',{'widget':widget,'input_dict':input_dict,'output_dict':output_dict})
......@@ -226,59 +218,6 @@ def term_candidate_viewer(request, input_dict, output_dict, widget):
terms = sorted(terms, key = lambda x: x['score'], reverse=True)
return render(request, 'visualizations/terms.html', {'widget' : widget, 'terms' : terms})
def sensitivity_analysis_viewer(request, input_dict, output_dict, widget):
'''
Computes the sensitivity analysis graph.
@author: Anze Vavpeltic, 2012
'''
model = input_dict['model']
attributes = [att.name for att in input_dict['model'].data.domain.features]
data_points = {}
domain = range(0, 101, 10)
# Compute for each attribute
for target_att in attributes:
y, ex_data = [], {}
# For collecting scores for each example across different weights
for ex in model.data:
ex_data[ex['label'].value] = []
# Compute the scores for each weight
for w in domain:
model.weights[target_att] = w
ds = model()
for ex in ds:
ex_data[ex['label'].value].append([w, ex['score'].value])
for ex in model.data:
y.append({'name' : ex['label'].value, 'data' : ex_data[ex['label'].value]})
data_points[target_att] = y
return render(request, 'visualizations/sensitivity_analysis.html',
{'widget' : widget,
'attributes': attributes,
'data_points' : json.dumps(data_points),
'output_dict': {}
})
def ds_charts_viewer(request, input_dict, output_dict, widget):
model = input_dict['model']
norm_data = model()
weight_shares = [ [att, weight] for att, weight in model.weights.items() ]
attributes = sorted(model.weights.keys())
alternatives = [ex['label'].value for ex in norm_data]
weights_bar = [{ 'data' : [model.weights[att] for att in attributes] }]
values_column = [{ 'data' : [ex['score'].value for ex in norm_data] }]
alt_data = [{ 'name' : ex['label'].value, 'data' : [ex[att].value for att in attributes] } for ex in norm_data ]
return render(request, 'visualizations/ds_charts.html',
{'widget' : widget,
'model_name' : model.name,
'attributes' : json.dumps(attributes),
'alternatives' : json.dumps(alternatives),
'weight_shares' : json.dumps(weight_shares),
'weights_bar' : json.dumps(weights_bar),
'values_column' : json.dumps(values_column),
'alt_data' : json.dumps(alt_data)
})
#------------------------------------------------------------------------------
# LATINO INTERFACE
#------------------------------------------------------------------------------
......
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