Added support of functions to be applied on each nodes

megaRefact
Sami Mokaddem 2018-08-23 08:59:51 +00:00
parent 154835f9eb
commit 7e54b8833d
3 changed files with 145 additions and 21 deletions

View File

@ -12,8 +12,14 @@
var ProxyMapper = function(mapping, data, options) { var ProxyMapper = function(mapping, data, options) {
this.mapping = mapping; this.mapping = mapping;
this.data = data; this.data = data;
console.log(options);
this._default_options = { this._default_options = {
fillValue: 0 fillValue: 0,
functions: {
dates: function (value) {return value;},
labels: function (value) {return value;},
values: function (value) {return value;}
}
}; };
this.options = $.extend({}, this._default_options, options); this.options = $.extend({}, this._default_options, options);
this.result = {}; this.result = {};
@ -50,7 +56,8 @@
let val = intermediate[index]; let val = intermediate[index];
if (that.mappingI2[val] === undefined) { if (that.mappingI2[val] === undefined) {
that.mappingI2[val] = that.result['dates'].length; that.mappingI2[val] = that.result['dates'].length;
that.result['dates'].push(val); let nval = that.options.functions.dates(val);
that.result['dates'].push(nval);
} }
}; };
this.iter(intermediate, instructions, matchingFun, {}); this.iter(intermediate, instructions, matchingFun, {});
@ -68,7 +75,8 @@
val.push(that.options.fillValue); val.push(that.options.fillValue);
} }
} }
that.result[label] = val; let nval = that.options.functions.dates(val);
that.result[label] = nval;
} }
} else { } else {
let label = intermediate[index]; let label = intermediate[index];
@ -78,7 +86,8 @@
val.push(that.options.fillValue); val.push(that.options.fillValue);
} }
} }
that.result[label] = val; let nlabel = that.options.functions.labels(label);
that.result[nlabel] = val;
} }
}; };
this.iter(intermediate, instructions, matchingFun, {valueLength: this.result.dates.length}); this.iter(intermediate, instructions, matchingFun, {valueLength: this.result.dates.length});
@ -92,7 +101,9 @@
let i1 = additionalData.i1; let i1 = additionalData.i1;
let i2 = additionalData.i2; let i2 = additionalData.i2;
let i2_adjusted = that.mappingI2[i2]; let i2_adjusted = that.mappingI2[i2];
that.result[i1][i2_adjusted] = val; let ni1 = that.options.functions.labels(i1);
let nval = that.options.functions.values(val);
that.result[ni1][i2_adjusted] = nval;
}; };
this.iter(intermediate, instructions, matchingFun, {mapping: this.mapping}); this.iter(intermediate, instructions, matchingFun, {mapping: this.mapping});
}, },

View File

@ -20,9 +20,10 @@
depth: 5 depth: 5
}, },
maxCharDisplay: 20, maxCharDisplay: 20,
itemColors: ['#fc440f', '#a5e12e', '#5d2e8c', '#2ec4b6', '#65524d', '#adcad6', '#99c24d'], itemColors: ['#337ab7', '#5cb85c', '#d9534f', '#f0ad4e', '#d9edf7', '#dff0d8', '#f2dede', '#fcf8e3'],
duration: 500, duration: 500,
interaction: true, interaction: true,
default_function: ' return value;',
toBeMapped: [] toBeMapped: []
}; };
this.options = $.extend({}, this._default_options, options); this.options = $.extend({}, this._default_options, options);
@ -364,7 +365,7 @@
}); });
res.style('fill', itemColor) res.style('fill', itemColor)
.style('fill-opacity', 0.85); .style('fill-opacity', 1.0);
// find all paths // find all paths
var paths = []; var paths = [];
@ -492,22 +493,37 @@
var that = this; var that = this;
this.mappingDomTable = $('<table class="table mappingTable"></table>'); this.mappingDomTable = $('<table class="table mappingTable"></table>');
var thead = $('<thead></thead>') var thead = $('<thead></thead>')
var tbody = $('<thead></thead>') var tbody = $('<tbody></tbody>')
var row1 = $('<tr></tr>'); var row1 = $('<tr></tr>');
var row2 = $('<tr style="height: 20px;"></tr>'); var row2 = $('<tr style="height: 20px;"></tr>');
var row3 = $('<tr style="height: 20px;"></tr>');
this.options.toBeMapped.forEach(function(item, index) { this.options.toBeMapped.forEach(function(item, index) {
var itemColor = that.options.itemColors[index]; var itemColor = that.options.itemColors[index];
var cellH = $('<th>'+item+'</th>'); var cellH = $('<th data-map="'+item+'">'+item+'</th>');
var cellB = $('<td id="'+item+'Cell"></td>'); var cellB = $('<td id="'+item+'Cell" data-map="'+item+'"></td>');
var cellB2 = $('<td id="'+item+'CellFun" class="cellFunInput" data-map="'+item+'"></td>');
var fun_head = $('<span><span style="color: mediumblue;">function</span> (value, datum) {</span>');
var fun_foot = $('<span>}</span>');
var fun_foot_res = $('<span class="funResText">&gt <span style="color: mediumblue;">function</span> (<span id="funXInput-'+item+'">x</span>, d) = <span id="funXOuput-'+item+'">x</span></span>');
var fun_input = $('<textarea id="'+item+'" rows="1"></textarea>');
fun_input.val(that.options.default_function);
cellB2.append(fun_head);
cellB2.append(fun_input);
cellB2.append(fun_foot);
cellB2.append(fun_foot_res);
cellH.click(function() { that.set_current_mapping_item(item); }); cellH.click(function() { that.set_current_mapping_item(item); });
cellB.click(function() { that.set_current_mapping_item(item); }); cellB.click(function() { that.set_current_mapping_item(item); });
cellB2.click(function() { that.set_current_mapping_item(item); });
that.set_color(cellH, itemColor); that.set_color(cellH, itemColor);
that.set_color(cellB, itemColor); that.set_color(cellB, itemColor);
that.set_color(cellB2, itemColor);
row1.append(cellH); row1.append(cellH);
row2.append(cellB); row2.append(cellB);
row3.append(cellB2);
}); });
thead.append(row1); thead.append(row1);
tbody.append(row2); tbody.append(row2);
tbody.append(row3);
this.mappingDomTable.append(thead); this.mappingDomTable.append(thead);
this.mappingDomTable.append(tbody); this.mappingDomTable.append(tbody);
this.fillValueDomInput = $('<input class="form-control" placeholder="0" value="empty">'); this.fillValueDomInput = $('<input class="form-control" placeholder="0" value="empty">');
@ -522,6 +538,9 @@
this.fillValueDomInput.on('input', function() { this.fillValueDomInput.on('input', function() {
that.update_result_tree(); that.update_result_tree();
}); });
$('.mappingTable textarea').on('input', function() {
that.update_result_tree();
});
}, },
set_color: function(item, color) { set_color: function(item, color) {
@ -560,11 +579,14 @@
} }
} }
this.mappingDomTable.find('td').addClass('grey'); this.mappingDomTable.find('td').addClass('grey');
this.mappingDomTable.find('th').addClass('grey');
this.mappingDomTable.find('td').removeClass('picking'); this.mappingDomTable.find('td').removeClass('picking');
var cell = this.mappingDomTable.find('#'+name+'Cell'); this.mappingDomTable.find('th').removeClass('picking');
//var cell = this.mappingDomTable.find('#'+name+'Cell');
var cells = this.mappingDomTable.find('[data-map="'+name+'"]');
var itemColor = this.itemColors.get(name); var itemColor = this.itemColors.get(name);
cell.removeClass('grey'); cells.removeClass('grey');
this.currentPickingCell = cell; this.currentPickingCell = this.mappingDomTable.find('#'+name+'Cell');
this.currentPicking = name; this.currentPicking = name;
}, },
@ -581,12 +603,28 @@
interaction: false interaction: false
}; };
//var result = new $.proxyMapper(this.instructions, this.data, {}); var continue_update = this.render_functions_output();
if (!continue_update) {
return
}
// collect functions
var functions = {};
$('.mappingTable textarea').each(function() {
var dom = $(this);
var f_body = dom.val();
functions[dom[0].id] = new Function('value', 'd', f_body);
});
// perform mapping
var pm_options = { var pm_options = {
fillValue: this.fillValueDomInput.val() fillValue: this.fillValueDomInput.val(),
functions: functions
}; };
var adjustedInstructions = this.adjust_instruction(); var adjustedInstructions = this.adjust_instruction();
var result = new $.proxyMapper(adjustedInstructions, this.data, pm_options); var result = new $.proxyMapper(adjustedInstructions, this.data, pm_options);
// destroy and redraw
this.treeDivResult[0].innerHTML = ''; this.treeDivResult[0].innerHTML = '';
new TreeFromJson(this.treeDivResult, result, options); new TreeFromJson(this.treeDivResult, result, options);
}, },
@ -628,6 +666,40 @@
return adjustedInstructions; return adjustedInstructions;
}, },
render_functions_output: function() {
var that = this;
var flag_continue = true;
$('.mappingTable textarea').each(function() {
var c_id = $(this).attr('id');
var f_body = $(this).val();
var funXInput = $('#funXInput-'+c_id);
var funXOuput = $('#funXOuput-'+c_id);
// check if valid function
try {
var f = new Function('value', 'd', f_body);
var nodes = that.svg.selectAll(".node circle").filter(
function(d) { return d.picked === c_id;}
);
var x = nodes.data()[0].name;
funXInput.text('"'+that.adjust_text_length(x)+'"');
funXOuput[0].innerHTML = that.adjust_text_length('"'+f(x)+'"');
} catch(err) { // Error
if (err.name == 'SyntaxError') {
flag_continue = false;
funXOuput[0].innerHTML = $('<span class="funOutputError">'+err.name+'</span>')[0].outerHTML;
} else if (err.name == 'TypeError') {
var html = $('<span></span>');
html.append($('<span class="funOutputError">'+'Not picked yet'+'</span>'));
html.append($('<span class="funOutputError">'+err.name+'</span>'));
funXOuput[0].innerHTML = html[0].outerHTML;
} else {
funXOuput[0].innerHTML = $('<span class="funOutputError">'+err.name+'</span>')[0].outerHTML;
}
}
});
return flag_continue;
},
isObject: function(v) { isObject: function(v) {
return v !== null && typeof v === 'object'; return v !== null && typeof v === 'object';
}, },
@ -636,11 +708,12 @@
if (text === undefined || text === '') { if (text === undefined || text === '') {
return ''; return '';
} }
text = text.slice(0, this.options.maxCharDisplay); text = new String(text);
var textSliced = text.slice(0, this.options.maxCharDisplay);
if (text.length > this.options.maxCharDisplay) { if (text.length > this.options.maxCharDisplay) {
text += '...'; textSliced += '...';
} }
return text; return textSliced;
}, },
create_tree: function(root, linkname, depth, maxDepth, maxWidth) { create_tree: function(root, linkname, depth, maxDepth, maxWidth) {

View File

@ -40,7 +40,12 @@
} }
.node circle { .node circle {
fill: #fff; fill: #fff;
stroke: steelblue; stroke: lightgrey;
stroke-width: 3px;
}
.node rect {
fill: #fff;
stroke: lightgrey;
stroke-width: 3px; stroke-width: 3px;
} }
.node text { .node text {
@ -55,7 +60,8 @@
.mappingTable { .mappingTable {
display: inline-table !important; display: inline-table !important;
cursor: pointer; cursor: pointer;
width: 50%; min-width: 50%;
max-width: 75%;
} }
.mappingTableDivConfig { .mappingTableDivConfig {
@ -73,7 +79,36 @@
} }
td.grey { td.grey {
background-color: grey !important; filter: opacity(60%) grayscale(30%);
}
th.grey {
filter: opacity(60%) grayscale(30%);
}
.mappingTable td.cellFunInput {
padding: 0px;
font-family: Consolas,"courier new";
}
.cellFunInput textarea {
color: black;
width: 100%;
}
.cellFunInput > span {
display: block;
}
.funOutputError {
color: red;
background: white;
padding: 3px;
border-radius: 4px;
margin-right: 5px;
}
.funResText {
font-size: 12px;
} }
.linkText { .linkText {
@ -85,6 +120,9 @@
stroke: #ddd; stroke: #ddd;
stroke-width: 2; stroke-width: 2;
} }
.linkLabel {
cursor: pointer;
}
.json_key { .json_key {
color: #690; color: #690;
@ -131,6 +169,8 @@
var endpoint = []; var endpoint = [];
var tfj; var tfj;
$.getJSON('{{ url_for("testData") }}', function(data) { $.getJSON('{{ url_for("testData") }}', function(data) {
//$.getJSON('{{ url_for("getTrendingSightings") }}', function(data) {
//$.getJSON('{{ url_for("getUserLoginsAndContribOvertime") }}', function(data) {
var depth = 5; var depth = 5;
var width = 3; var width = 3;