Commit 72d500c1 by Valera Rozuvan Committed by Alexander Kryklia

Feature "Dynamic Elements in Labels" has been refactored to provide the user an…

Feature "Dynamic Elements in Labels" has been refactored to provide the user an easier interface for access. Demo "Sample Size and Power" has been updated.
parent 20227d21
...@@ -37,6 +37,7 @@ class GraphicalSliderToolModule(XModule): ...@@ -37,6 +37,7 @@ class GraphicalSliderToolModule(XModule):
resource_string(__name__, 'js/src/graphical_slider_tool/inputs.js'), resource_string(__name__, 'js/src/graphical_slider_tool/inputs.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'), resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'), resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'),
resource_string(__name__, 'js/src/graphical_slider_tool/gst.js') resource_string(__name__, 'js/src/graphical_slider_tool/gst.js')
] ]
......
// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {
define('GLabelElOutput', ['logme'], function (logme) {
return GLabelElOutput;
function GLabelElOutput(config, state) {
if ($.isPlainObject(config.functions.function)) {
processFuncObj(config.functions.function);
} else if ($.isArray(config.functions.function)) {
(function (c1) {
while (c1 < config.functions.function.length) {
if ($.isPlainObject(config.functions.function[c1])) {
processFuncObj(config.functions.function[c1]);
}
c1 += 1;
}
}(0));
}
return;
function processFuncObj(obj) {
var paramNames, funcString, func;
// We are only interested in functions that are meant for output to an
// element.
if (
(typeof obj['@output'] !== 'string') ||
(obj['@output'].toLowerCase() !== 'plot_label')
) {
return;
}
if (typeof obj['@el_id'] !== 'string') {
logme('ERROR: You specified "output" as "plot_label", but did not spify "el_id".');
return;
}
if (typeof obj['#text'] !== 'string') {
logme('ERROR: Function body is not defined.');
return;
}
funcString = obj['#text'];
// Make sure that all HTML entities are converted to their proper
// ASCII text equivalents.
funcString = $('<div>').html(funcString).text();
paramNames = state.getAllParameterNames();
paramNames.push(funcString);
try {
func = Function.apply(null, paramNames);
} catch (err) {
logme(
'ERROR: The function body "' +
funcString +
'" was not converted by the Function constructor.'
);
logme('Error message: "' + err.message + '".');
$('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not create a function from string "' + funcString + '".' + '</div>');
$('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>');
paramNames.pop();
return;
}
paramNames.pop();
state.plde.push({
'elId': obj['@el_id'],
'func': func
});
}
}
});
// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
...@@ -155,7 +155,10 @@ define('Graph', ['logme'], function (logme) { ...@@ -155,7 +155,10 @@ define('Graph', ['logme'], function (logme) {
} }
newAsyObj.label = false; newAsyObj.label = false;
if (typeof asyObj['@label'] === 'string') { if (
(asyObj.hasOwnProperty('@label') === true) &&
(typeof asyObj['@label'] === 'string')
) {
newAsyObj.label = asyObj['@label']; newAsyObj.label = asyObj['@label'];
} }
...@@ -492,7 +495,10 @@ define('Graph', ['logme'], function (logme) { ...@@ -492,7 +495,10 @@ define('Graph', ['logme'], function (logme) {
// properties as parameters. Rather than writing them out every // properties as parameters. Rather than writing them out every
// time, we will have a single place where it is done. // time, we will have a single place where it is done.
function callAddFunction(obj) { function callAddFunction(obj) {
if (typeof obj['@output'] === 'string') { if (
(obj.hasOwnProperty('@output')) &&
(typeof obj['@output'] === 'string')
) {
// If this function is meant to be calculated for an // If this function is meant to be calculated for an
// element then skip it. // element then skip it.
...@@ -500,13 +506,24 @@ define('Graph', ['logme'], function (logme) { ...@@ -500,13 +506,24 @@ define('Graph', ['logme'], function (logme) {
return; return;
} }
// It is an error if "output" is not "element" or "graph". // If this function is meant to be calculated for a
// Though you can ommit the "output" attribute. // dynamic element in a label then skip it.
else if (obj['@output'].toLowerCase() === 'plot_label') {
return;
}
// It is an error if '@output' is not 'element',
// 'plot_label', or 'graph'. However, if the '@output'
// attribute is omitted, we will not have reached this.
else if (obj['@output'].toLowerCase() !== 'graph') { else if (obj['@output'].toLowerCase() !== 'graph') {
logme('ERROR: Function "output" attribute can be either "div" or "graph".'); logme(
'ERROR: Function "output" attribute can be ' +
'either "element", "plot_label", or "graph".'
);
return; return;
} }
} }
// The user did not specify an "output" attribute, or it is // The user did not specify an "output" attribute, or it is
...@@ -526,7 +543,8 @@ define('Graph', ['logme'], function (logme) { ...@@ -526,7 +543,8 @@ define('Graph', ['logme'], function (logme) {
function addFunction(funcString, color, line, dot, label, function addFunction(funcString, color, line, dot, label,
pointSize, fillArea, bar, disableAutoReturn) { pointSize, fillArea, bar, disableAutoReturn) {
var newFunctionObject, func, paramNames, matches;
var newFunctionObject, func, paramNames, c1, rgxp;
// The main requirement is function string. Without it we can't // The main requirement is function string. Without it we can't
// create a function, and the series cannot be calculated. // create a function, and the series cannot be calculated.
...@@ -678,18 +696,27 @@ define('Graph', ['logme'], function (logme) { ...@@ -678,18 +696,27 @@ define('Graph', ['logme'], function (logme) {
} }
if (typeof label === 'string') { if (typeof label === 'string') {
matches = label.match(/%%_[^%]*%%/g);
if ( newFunctionObject.specialLabel = false;
($.isArray(matches) === true) && newFunctionObject.pldeHash = [];
(matches.length > 0)
) { // Let's check the label against all of the plde objects.
newFunctionObject['specialLabel'] = true; // plde is an abbreviation for Plot Label Dynamic Elements.
} else { for (c1 = 0; c1 < state.plde.length; c1 += 1) {
newFunctionObject['specialLabel'] = false; rgxp = new RegExp(state.plde[c1].elId, 'g');
// If we find a dynamic element in the label, we will
// hash the current plde object, and indicate that this
// is a special label.
if (rgxp.test(label) === true) {
newFunctionObject.specialLabel = true;
newFunctionObject.pldeHash.push(state.plde[c1]);
}
} }
newFunctionObject['label'] = label; newFunctionObject.label = label;
} else {
newFunctionObject.label = false;
} }
functions.push(newFunctionObject); functions.push(newFunctionObject);
...@@ -706,7 +733,7 @@ define('Graph', ['logme'], function (logme) { ...@@ -706,7 +733,7 @@ define('Graph', ['logme'], function (logme) {
function generateData() { function generateData() {
var c0, c1, functionObj, seriesObj, dataPoints, paramValues, x, y, var c0, c1, functionObj, seriesObj, dataPoints, paramValues, x, y,
start, end, step, tempX, matches; start, end, step, tempX;
paramValues = state.getAllParameterValues(); paramValues = state.getAllParameterValues();
...@@ -818,33 +845,27 @@ define('Graph', ['logme'], function (logme) { ...@@ -818,33 +845,27 @@ define('Graph', ['logme'], function (logme) {
} }
// See if a user defined a label for this function. // See if a user defined a label for this function.
if (functionObj.hasOwnProperty('label') === true) { if (functionObj.label !== false) {
if (functionObj.specialLabel === true) { if (functionObj.specialLabel === true) {
matches = functionObj.label.match(/%%_[^%]*%%/g);
if ($.isArray(matches) === true) {
(function (c1) { (function (c1) {
var el_id, func, tempLabel; var tempLabel;
tempLabel = functionObj.label; tempLabel = functionObj.label;
while (c1 < matches.length) { while (c1 < functionObj.pldeHash.length) {
el_id = matches[c1].replace(/%/g, '');
func = state.getFuncForSpecialLabel(el_id);
if (func !== null) {
tempLabel = tempLabel.replace( tempLabel = tempLabel.replace(
matches[c1], functionObj.pldeHash[c1].elId,
func.apply(window, state.getAllParameterValues()) functionObj.pldeHash[c1].func.apply(
window,
state.getAllParameterValues()
)
); );
}
c1 += 1; c1 += 1;
} }
seriesObj.label = tempLabel; seriesObj.label = tempLabel;
}(0)); }(0));
}
} else { } else {
seriesObj.label = functionObj.label; seriesObj.label = functionObj.label;
} }
...@@ -880,13 +901,22 @@ define('Graph', ['logme'], function (logme) { ...@@ -880,13 +901,22 @@ define('Graph', ['logme'], function (logme) {
} }
for (c0 = 0; c0 < asymptotes.length; c0 += 1) { for (c0 = 0; c0 < asymptotes.length; c0 += 1) {
if (typeof asymptotes[c0].label === 'string') {
// If the user defined a label for this asympote, then the
// property 'label' will be a string (in the other case it is
// a boolean value 'false'). We will create an empty data set,
// and add to it a label. This solution is a bit _wrong_ , but
// it will have to do for now. Flot JS does not provide a way
// to add labels to markings, and we use markings to generate
// asymptotes.
if (asymptotes[c0].label !== false) {
dataSeries.push({ dataSeries.push({
'data': [], 'data': [],
'label': asymptotes[c0].label, 'label': asymptotes[c0].label,
'color': asymptotes[c0].color 'color': asymptotes[c0].color
}); });
} }
} }
return true; return true;
......
...@@ -8,8 +8,8 @@ define( ...@@ -8,8 +8,8 @@ define(
// Even though it is not explicitly in this module, we have to specify // Even though it is not explicitly in this module, we have to specify
// 'GeneralMethods' as a dependency. It expands some of the core JS objects // 'GeneralMethods' as a dependency. It expands some of the core JS objects
// with additional useful methods that are used in other modules. // with additional useful methods that are used in other modules.
['State', 'GeneralMethods', 'Sliders', 'Inputs', 'Graph', 'ElOutput', 'logme'], ['State', 'GeneralMethods', 'Sliders', 'Inputs', 'Graph', 'ElOutput', 'GLabelElOutput', 'logme'],
function (State, GeneralMethods, Sliders, Inputs, Graph, ElOutput, logme) { function (State, GeneralMethods, Sliders, Inputs, Graph, ElOutput, GLabelElOutput, logme) {
return GstMain; return GstMain;
...@@ -67,6 +67,10 @@ define( ...@@ -67,6 +67,10 @@ define(
// Configure functions that output to an element instead of the graph. // Configure functions that output to an element instead of the graph.
ElOutput(config, state); ElOutput(config, state);
// Configure functions that output to an element instead of the graph
// label.
GLabelElOutput(config, state);
// Configure and display the graph. Attach event for the graph to be // Configure and display the graph. Attach event for the graph to be
// updated on any change of a slider or a text input. // updated on any change of a slider or a text input.
Graph(gstId, config, state); Graph(gstId, config, state);
......
...@@ -98,7 +98,10 @@ define('State', ['logme'], function (logme) { ...@@ -98,7 +98,10 @@ define('State', ['logme'], function (logme) {
'bindUpdatePlotEvent': bindUpdatePlotEvent, 'bindUpdatePlotEvent': bindUpdatePlotEvent,
'addDynamicEl': addDynamicEl, 'addDynamicEl': addDynamicEl,
'getFuncForSpecialLabel': getFuncForSpecialLabel 'getFuncForSpecialLabel': getFuncForSpecialLabel,
// plde is an abbreviation for Plot Label Dynamic Elements.
plde: []
}; };
function getAllParameterNames() { function getAllParameterNames() {
......
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