Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Domain hierarchy display #676

Closed
wants to merge 8 commits into from
183 changes: 159 additions & 24 deletions resource/js/hierarchy.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,57 @@ function createConceptObject(conceptUri, conceptData) {
*/
function attachTopConceptsToSchemes(schemes, currentNode, parentData) {
for (var i = 0; i < schemes.length; i++) {
if (schemes[i].uri === parentData[currentNode.uri].top) {
if(Object.prototype.toString.call(schemes[i].children) !== '[object Array]' ) {
schemes[i].children = [];
}
schemes[i].children.push(currentNode);
// the hierarchy response contains the parent info before the topConcepts so it's a safe to open the first one without broaders
if (!schemes.opened && !currentNode.broader) {
schemes[i].state = currentNode.state;
schemes.opened = true;
}
}
// search if top concept uri is equal to scheme uri on first level
// search in all the 'tops' key
for (var j = 0; j < parentData[currentNode.uri].tops.length; j++) {
var currentTop = parentData[currentNode.uri].tops[j];
// we found a scheme at the first level that is equal to one of the 'tops' value
if(schemes[i].uri===currentTop){
if(Object.prototype.toString.call(schemes[i].children) !== '[object Array]' ) {
schemes[i].children = [];
}
// append to a first-level node that corresponds to a concept scheme
schemes[i].children.push(currentNode);

// the hierarchy response contains the parent info before the topConcepts so it's a safe to open the first one without broaders
if (!schemes[i].opened && !currentNode.broader) {
schemes[i].state = currentNode.state;
schemes.opened = true;
}
break;
}
}

// search if top concept uri is equal to scheme children uri, if there are children (second level)
// this may be the case if schemes are organised by subjects : subjects will be first-level nodes, concepts schemes will be second level
for (var h = 0; h <schemes[i].children.length; h++) {
// one of the second-level node, actually corresponding to a concept scheme inside a 'domain' node
var currentScheme = schemes[i].children[h];

// search in all the 'tops' key
for (var j = 0; j < parentData[currentNode.uri].tops.length; j++) {
var currentTop = parentData[currentNode.uri].tops[j];

// we found a scheme at the second level that is equal to one of the 'tops' value
if(currentScheme.uri===currentTop) {
if(Object.prototype.toString.call(currentScheme.children) !== '[object Array]' ) {
currentScheme.children = [];
}
currentScheme.children.push(currentNode);

// the hierarchy response contains the parent info before the topConcepts so it's a safe to open the first one without broaders
if (!currentScheme.opened && !currentNode.broader) {
// open the first-level node and second-level node
schemes[i].state = currentNode.state;
currentScheme.state=schemes[i].state;
currentScheme.opened=true;
currentScheme.children.opened=true;
}
break;
}
}
}

}
return schemes;
}
Expand Down Expand Up @@ -281,7 +321,7 @@ function getParams(node) {
return $.param({'uri' : nodeId, 'lang' : clang});
}

function pickLabelFromScheme(scheme) {
function pickLabel(scheme) {
var label = '';
if (scheme.prefLabel)
label = scheme.prefLabel;
Expand All @@ -294,19 +334,91 @@ function pickLabelFromScheme(scheme) {

function schemeRoot(schemes) {
var topArray = [];


// Step 1 : gather domain list
var domains=[];
for (var i = 0; i < schemes.length; i++) {
var scheme = schemes[i];
var label = pickLabelFromScheme(scheme);
if (label !== '') { // hiding schemes without a label/title
var schemeObject = {
text: label,
a_attr : { "href" : vocab + '/' + lang + '/page/?uri=' + scheme.uri, 'class': 'scheme'},
uri: scheme.uri,
children: true,
state: { opened: false }
};
topArray.push(schemeObject);
if(schemes[i].subject != null) {
var schemeDomain = schemes[i].subject.uri;

// test if domain was already found
var found = false;
for (var k = 0; k < domains.length; k++) {
if(domains[k].uri===schemeDomain){
found = true;
break;
}
}

// if not found, store it in domain list
if(!found) {
domains.push(schemes[i].subject);
}
}
}

// Step 2 : create tree nodes for each domain
for (var i = 0; i < domains.length; i++) {
var theDomain = domains[i];
var theDomainLabel = pickLabel(theDomain);

// avoid creating entries with empty labels
if(theDomainLabel != '') {
// Step 2.1 : create domain node without children
var domainObject = {
text: theDomainLabel,
// note that the class 'domain' will make sure the node will be sorted _before_ others (see the 'sort' functio nat the end)
a_attr : { "href" : vocab + '/' + lang + '/page/?uri=' + theDomain.uri, 'class': 'domain'},
uri: theDomain.uri,
children: [],
state: { opened: false }
};

// Step 2.2 : find the concept schemes in this domain and add them as children
for (var k = 0; k < schemes.length; k++) {
var theScheme = schemes[k];
var theSchemeLabel = pickLabel(theScheme);

// avoid creating entries with empty labels
if(theSchemeLabel != '') {
if((theScheme.subject) != null && (theScheme.subject.uri===theDomain.uri)) {
domainObject.children.push(
{
text: theSchemeLabel,
a_attr:{ "href" : vocab + '/' + lang + '/page/?uri=' + theScheme.uri, 'class': 'scheme'},
uri: theScheme.uri,
children: true,
state: { opened: false }
}
);
}
}
}
topArray.push(domainObject);
}

}

// Step 3 : add the schemes without any subjects after the subjects node
for (var k = 0; k < schemes.length; k++) {
var theScheme = schemes[k];

if(theScheme.subject == null) {
// avoid creating entries with empty labels
var theSchemeLabel = pickLabel(theScheme);
if(theSchemeLabel != '') {
topArray.push(
{
text:theSchemeLabel,
a_attr:{ "href" : vocab + '/' + lang + '/page/?uri=' + theScheme.uri, 'class': 'scheme'},
uri: theScheme.uri,
children: true,
state: { opened: false }
}
);
}
}
}
return topArray;
}
Expand Down Expand Up @@ -427,7 +539,30 @@ function getTreeConfiguration() {
}
},
'plugins' : ['sort'],
'sort' : function (a,b) { return naturalCompare(this.get_text(a).toLowerCase(), this.get_text(b).toLowerCase()); }
'sort' : function (a,b) {
var nodeA = this.get_node(a);
var nodeB = this.get_node(b);
// make sure the tree nodes with class 'domain' are sorted before the others
if(nodeA.a_attr && nodeA.a_attr['class']) {
if(nodeB.a_attr && nodeB.a_attr['class']) {
if(nodeA.a_attr['class'] == 'domain' && nodeB.a_attr['class'] == 'domain') {
return naturalCompare(this.get_text(a).toLowerCase(), this.get_text(b).toLowerCase());
}
else if(nodeA.a_attr['class'] == 'domain' && nodeB.a_attr['class'] != 'domain') {
return -1;
}
else if(nodeA.a_attr['class'] != 'domain' && nodeB.a_attr['class'] == 'domain') {
return 1;
}
} else {
// defaults to alphabetical ordering
return naturalCompare(this.get_text(a).toLowerCase(), this.get_text(b).toLowerCase());
}
} else {
// defaults to alphabetical ordering
return naturalCompare(this.get_text(a).toLowerCase(), this.get_text(b).toLowerCase());
}
}
});
}