StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.1 KiB
158 lines
4.1 KiB
4 years ago
|
/**
|
||
|
* JSON + Object references wrapper
|
||
|
*
|
||
|
* @author Hunter Loftis <hunter@skookum.com>
|
||
|
* @license The MIT license.
|
||
|
* @copyright Copyright (c) 2010 Skookum, skookum.com
|
||
|
*/
|
||
|
|
||
|
;(function() {
|
||
|
|
||
|
var CONTAINER_TYPES = {
|
||
|
'object': function() { return {}; },
|
||
|
'array': function() { return {}; },
|
||
|
'date': function() { return {}; },
|
||
|
'function': function() { return {}; }
|
||
|
};
|
||
|
|
||
|
var REFERENCE_FLAG = '_CRYO_REF_';
|
||
|
var INFINITY_FLAG = '_CRYO_INFINITY_';
|
||
|
var FUNCTION_FLAG = '_CRYO_FUNCTION_';
|
||
|
var UNDEFINED_FLAG = '_CRYO_UNDEFINED_';
|
||
|
var DATE_FLAG = '_CRYO_DATE_';
|
||
|
|
||
|
function typeOf(item) {
|
||
|
if (typeof item === 'object') {
|
||
|
if (item instanceof Array) return 'array';
|
||
|
if (item instanceof Date) return 'date';
|
||
|
return 'object';
|
||
|
}
|
||
|
return typeof item;
|
||
|
}
|
||
|
|
||
|
function stringify(item) {
|
||
|
var references = [];
|
||
|
var root = cloneWithReferences(item, references);
|
||
|
|
||
|
return JSON.stringify({
|
||
|
root: root,
|
||
|
references: references
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function cloneWithReferences(item, references, savedItems) {
|
||
|
savedItems = savedItems || [];
|
||
|
var type = typeOf(item);
|
||
|
var constructor = CONTAINER_TYPES[type];
|
||
|
|
||
|
// can this object contain its own properties?
|
||
|
if (constructor) {
|
||
|
var referenceIndex = savedItems.indexOf(item);
|
||
|
// do we need to store a new reference to this object?
|
||
|
if (referenceIndex === -1) {
|
||
|
var clone = constructor();
|
||
|
for (var key in item) {
|
||
|
if (item.hasOwnProperty(key)) {
|
||
|
clone[key] = cloneWithReferences(item[key], references, savedItems);
|
||
|
}
|
||
|
}
|
||
|
referenceIndex = references.push({
|
||
|
contents: clone,
|
||
|
value: wrap(item)
|
||
|
}) - 1;
|
||
|
savedItems[referenceIndex] = item;
|
||
|
}
|
||
|
|
||
|
// return something like _CRYO_REF_22
|
||
|
return REFERENCE_FLAG + referenceIndex;
|
||
|
}
|
||
|
|
||
|
// return a non-container object
|
||
|
return wrap(item);
|
||
|
}
|
||
|
|
||
|
function parse(string) {
|
||
|
var json = JSON.parse(string);
|
||
|
var root = json.root;
|
||
|
var references = json.references;
|
||
|
|
||
|
return rebuildFromReferences(root, references);
|
||
|
}
|
||
|
|
||
|
function rebuildFromReferences(item, references) {
|
||
|
if (starts(item, REFERENCE_FLAG)) {
|
||
|
var referenceIndex = 0 | item.slice(REFERENCE_FLAG.length);
|
||
|
var ref = references[referenceIndex];
|
||
|
var container = unwrap(ref.value);
|
||
|
var contents = ref.contents;
|
||
|
for (var key in contents) {
|
||
|
container[key] = rebuildFromReferences(contents[key], references);
|
||
|
}
|
||
|
return container;
|
||
|
}
|
||
|
return unwrap(item);
|
||
|
}
|
||
|
|
||
|
function wrap(item) {
|
||
|
var type = typeOf(item);
|
||
|
if (type === 'undefined') return UNDEFINED_FLAG;
|
||
|
if (type === 'function') return FUNCTION_FLAG + item.toString();
|
||
|
if (type === 'date') return DATE_FLAG + item.getTime();
|
||
|
if (item === Infinity) return INFINITY_FLAG;
|
||
|
return item;
|
||
|
}
|
||
|
|
||
|
function unwrap(val) {
|
||
|
if (typeOf(val) === 'string') {
|
||
|
if (val === UNDEFINED_FLAG) return undefined;
|
||
|
if (starts(val, FUNCTION_FLAG)) {
|
||
|
var fn = val.slice(FUNCTION_FLAG.length);
|
||
|
var argStart = fn.indexOf('(') + 1;
|
||
|
var argEnd = fn.indexOf(')', argStart);
|
||
|
var args = fn.slice(argStart, argEnd);
|
||
|
var bodyStart = fn.indexOf('{') + 1;
|
||
|
var bodyEnd = fn.lastIndexOf('}') - 1;
|
||
|
var body = fn.slice(bodyStart, bodyEnd);
|
||
|
return new Function(args, body);
|
||
|
}
|
||
|
if (starts(val, DATE_FLAG)) {
|
||
|
var dateNum = parseInt(val.slice(DATE_FLAG.length), 10);
|
||
|
return new Date(dateNum);
|
||
|
}
|
||
|
if (val === INFINITY_FLAG) return Infinity;
|
||
|
}
|
||
|
return val;
|
||
|
}
|
||
|
|
||
|
function starts(string, prefix) {
|
||
|
return typeOf(string) === 'string' && string.slice(0, prefix.length) === prefix;
|
||
|
}
|
||
|
|
||
|
// Exported object
|
||
|
Cryo = {
|
||
|
stringify: stringify,
|
||
|
parse: parse
|
||
|
};
|
||
|
|
||
|
// global on server, window in browser
|
||
|
var root = this;
|
||
|
|
||
|
// AMD / RequireJS
|
||
|
if (typeof define !== 'undefined' && define.amd) {
|
||
|
define('Cryo', [], function () {
|
||
|
return Cryo;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// node.js
|
||
|
else if (typeof module !== 'undefined' && module.exports) {
|
||
|
module.exports = Cryo;
|
||
|
}
|
||
|
|
||
|
// included directly via <script> tag
|
||
|
else {
|
||
|
root.Cryo = Cryo;
|
||
|
}
|
||
|
|
||
|
})();
|