diff --git a/kadmos/vistoms/templates/VISTOMS.html b/kadmos/vistoms/templates/VISTOMS.html index 47d2c4c08c6d95f65540cbf5297c087c3c0a6088..c6b1e9f9aca60a4180111476a119a0a1649bc753 100644 --- a/kadmos/vistoms/templates/VISTOMS.html +++ b/kadmos/vistoms/templates/VISTOMS.html @@ -985,7 +985,7 @@ +"<ol><li>With a right-click on an edge (connecting lines between the competences) you can take a closer look at the data processed between those competences.</li>" +"<li>When you hover over one of the competences with the mouse, the respective input and output connections are highlighted. Input connections are highlighted in red, output connections in green.</li>" +"<li>Click right on a competence for more information, such as input/output data or a detailed tool description.</li>" - +"<li>To view the full data modeldata model, go to the \"Data model\" box and select a variable categorization.</li></ol><br />" + +"<li>To view the full data model, go to the \"Data model\" box and select a variable categorization.</li></ol><br />" +"<p>To switch to another visualization (<i>Edge Bundles</i> or <i>Sankey Diagram</i>), go to the navigation bar and select a graph from the drop down menu.</p>" +"<p>If you need more information on how to use the visualization package, click on the \"Tutorial\" button below.</p>" +"<p><br/>Any questions or feedback? Contact the support team with the \"Feedback\" button below!</p>" @@ -18752,71 +18752,67 @@ { //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) + function highlight(data) { - aText = "/"+data.data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - scenarioKeys.forEach(function(k) - { - var xdsm_tmp; - xdsm_tmp = xdsms[k]; - if (xdsm_tmp) - { - xdsm_tmp.svg.selectAll(".edge").each(function(p) - { - var firstElement_tmp = p.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.name,text_fromFirst)) - { - var highlightEdge = d3.select(this).select("polygon"); - highlightEdge - .style("stroke-width",5.) - .style("stroke","#CC0000") - d3.selectAll(".treeFrame") - .attr("fill-opacity", 0.5) - .attr("stroke-opacity", 0.5); - d3.selectAll(".nodeText").style("fill-opacity",0.5); - } - }) - } - }) - } + var xPath = data.data.xPath; + + scenarioKeys.forEach(function(k) + { + var xdsm_tmp; + xdsm_tmp = xdsms[k]; + if (xdsm_tmp) + { + xdsm_tmp.svg.selectAll(".edge").each(function(p) + { + var firstElement_tmp = p.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+xPath.split(firstElement_tmp)[1] + if (include(p.name,text_fromFirst)) + { + var highlightEdge = d3.select(this).select("polygon"); + highlightEdge + .style("stroke-width",5.) + .style("stroke","#CC0000") + d3.selectAll(".treeFrame") + .attr("fill-opacity", 0.5) + .attr("stroke-opacity", 0.5); + d3.selectAll(".nodeText").style("fill-opacity",0.5); + } + }) + } + }) + } //Unhighlight function again - function unhighlight(data,aText) + function unhighlight(data) { - aText = "/"+data.data.name+aText; - if (data.parent){unhighlight(data.parent,aText)} - else - { - scenarioKeys.forEach(function(k) - { - var xdsm_tmp; - xdsm_tmp = xdsms[k]; - if (xdsm_tmp) - { - xdsm_tmp.svg.selectAll(".edge").each(function(p) - { - var firstElement_tmp = p.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.name,text_fromFirst)) - { - var highlightEdge = d3.select(this).select("polygon"); - highlightEdge - .style("stroke-width",1.) - .style("stroke","black"); - d3.selectAll(".treeFrame") - .attr("fill-opacity", 0.8) - .attr("stroke-opacity", 0.8); - d3.selectAll(".nodeText").style("fill-opacity",1); - } - }) - } - }) - } + var xPath = data.data.xPath; + + scenarioKeys.forEach(function(k) + { + var xdsm_tmp; + xdsm_tmp = xdsms[k]; + if (xdsm_tmp) + { + xdsm_tmp.svg.selectAll(".edge").each(function(p) + { + var firstElement_tmp = p.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+xPath.split(firstElement_tmp)[1] + if (include(p.name,text_fromFirst)) + { + var highlightEdge = d3.select(this).select("polygon"); + highlightEdge + .style("stroke-width",1.) + .style("stroke","black"); + d3.selectAll(".treeFrame") + .attr("fill-opacity", 0.8) + .attr("stroke-opacity", 0.8); + d3.selectAll(".nodeText").style("fill-opacity",1); + } + }) + } + }) + } @@ -19077,12 +19073,10 @@ { title: 'Show usage of node in XDSM', onMouseDown: function(elm, d, i) { - var theText=""; - highlight(d,theText); + highlight(d); }, onMouseUp: function(elm, d, i) { - var theText=""; - unhighlight(d,theText); + unhighlight(d); }, onMouseOver: function(elm, d, i) { }, @@ -19785,7 +19779,7 @@ var graphElements = JSON.parse(result) - var title = "Here is a list of graph elements." + var title = "List view of graph elements." +" category: \"" + category + "\"" +", sub-category: \"" + sub_category + "\"" var message = ""; @@ -21072,8 +21066,6 @@ .on("click", function() { var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); - - //aigner: HIER WEITER! evtl. treeData aufbauen (buildTree) um nodeMenu einfacher zu machen variables.forEach(function(variable) { variable.name = variable.xPath @@ -21081,7 +21073,7 @@ variable.data = variable variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] }) - var title = "Here is a list" + var title = "List view: full variable set categorized according to " + varCategories[this.id].description showList(title,variables,nodeMenu) }) } @@ -21255,12 +21247,12 @@ { var edges = d3.selectAll(".edge"); var array=""; - var name; + var title; edges.each(function(edge) { if (io=="in") { - name = "Input tree view: " + aNode.id + "; Categorization: " + categoryDescr; + title = "List view of all inputs for " + aNode.id + "; Categorization: " + categoryDescr; if (edge.to == aNode.id) { array = array + "," + edge.name; @@ -21268,7 +21260,7 @@ } else if (io=="out") { - name = "Output tree view:" + aNode.id + "; Categorization: " + categoryDescr; + title = "List view of all outputs for " + aNode.id + "; Categorization: " + categoryDescr; if (edge.from == aNode.id) { array = array + "," + edge.name; @@ -21278,7 +21270,6 @@ var variables = []; var pipeData = array; - var title = "Here is a list" variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[aCategory])) prune_tree(pipeData,variables) variables.forEach(function(variable) @@ -21799,7 +21790,7 @@ onMouseClick: function(elm, data, i) { var variables = []; var pipeData = edge.name; - var title = "Here is a list" + var title = "List view: " + edge.from + " → " + edge.to + "; Categorization: " + data.description; variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) prune_tree(pipeData,variables) variables.forEach(function(variable) @@ -22825,57 +22816,53 @@ var classes = currentGraph.edgeBundles; //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) + function highlight(data) { - aText = "/"+data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else + var xPath = data.xPath + var allLinks = d3.selectAll(".edgeBundlesLink"); + allLinks[0].forEach(function(aLink) { - var allLinks = d3.selectAll(".edgeBundlesLink"); - allLinks[0].forEach(function(aLink) + + aLink.__data__.pipeData_in = aLink.__data__.source.pipeline_data[aLink.__data__.target.name]; + aLink.__data__.pipeData_out = aLink.__data__.target.pipeline_data[aLink.__data__.source.name]; + aLink.__data__.pipeDataName_in = ""; + aLink.__data__.pipeDataName_out = ""; + aLink.__data__.name = ""; + if (aLink.__data__.pipeData_in) { - - aLink.__data__.pipeData_in = aLink.__data__.source.pipeline_data[aLink.__data__.target.name]; - aLink.__data__.pipeData_out = aLink.__data__.target.pipeline_data[aLink.__data__.source.name]; - aLink.__data__.pipeDataName_in = ""; - aLink.__data__.pipeDataName_out = ""; - aLink.__data__.name = ""; - if (aLink.__data__.pipeData_in) + for (var i=0; i<aLink.__data__.pipeData_in.length; i++) { - for (var i=0; i<aLink.__data__.pipeData_in.length; i++) - { - if (i==0){aLink.__data__.pipeDataName_in += aLink.__data__.pipeData_in[i];} - else{aLink.__data__.pipeDataName_in += "," + aLink.__data__.pipeData_in[i];} - - } - aLink.__data__.name += aLink.__data__.pipeDataName_in - } - if (aLink.__data__.pipeData_out) - { - for (var i=0; i<aLink.__data__.pipeData_out.length; i++) - { - if (i==0){aLink.__data__.pipeDataName_out += aLink.__data__.pipeData_out[i];} - else{aLink.__data__.pipeDataName_out += "," + aLink.__data__.pipeData_out[i];} - } - aLink.__data__.name += aLink.__data__.pipeDataName_out - } - }) - - //var allLinks_tmp = allLinks[0]; - allLinks[0].forEach(function(p) { - var firstElement_tmp = p.__data__.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.__data__.name,text_fromFirst)) - { - d3.select(p) - .style("stroke-opacity", 1.0) + if (i==0){aLink.__data__.pipeDataName_in += aLink.__data__.pipeData_in[i];} + else{aLink.__data__.pipeDataName_in += "," + aLink.__data__.pipeData_in[i];} + } - else + aLink.__data__.name += aLink.__data__.pipeDataName_in + } + if (aLink.__data__.pipeData_out) + { + for (var i=0; i<aLink.__data__.pipeData_out.length; i++) { - d3.select(p).style("stroke-opacity", 0); + if (i==0){aLink.__data__.pipeDataName_out += aLink.__data__.pipeData_out[i];} + else{aLink.__data__.pipeDataName_out += "," + aLink.__data__.pipeData_out[i];} } - }); - } + aLink.__data__.name += aLink.__data__.pipeDataName_out + } + }) + + //var allLinks_tmp = allLinks[0]; + allLinks[0].forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+xPath.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p) + .style("stroke-opacity", 1.0) + } + else + { + d3.select(p).style("stroke-opacity", 0); + } + }); } //Function writeTreeToXML goes through tree nodes and puts the into an xml document @@ -23108,8 +23095,7 @@ onMouseDown: function(elm, d, i) { d3.selectAll(".treeFrame").attr("fill-opacity", .5); d3.selectAll(".nodeText").style("fill-opacity", 0.5); - var theText=""; - highlight(d,theText); + highlight(d); }, onMouseUp: function(elm, d, i) { d3.selectAll(".edgeBundlesLink") @@ -23294,8 +23280,6 @@ .on("click", function() { var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); - - //aigner: HIER WEITER! evtl. treeData aufbauen (buildTree) um nodeMenu einfacher zu machen variables.forEach(function(variable) { variable.name = variable.xPath @@ -23303,7 +23287,7 @@ variable.data = variable variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] }) - var title = "Here is a list" + var title = "List view: full variable set categorized according to " + varCategories[this.id].description showList(title,variables,nodeMenu) }) } @@ -23554,7 +23538,7 @@ varCategory: varCategories[j].name, description: varCategories[j].description, onMouseClick: function(elm, data, i) { - var title = "Here is a list" + var title = "List view of variable flow: " + elm.__data__.source.id + " → " + elm.__data__.target.id + "; Categorization: " + data.description; var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],elm.__data__) variables.forEach(function(variable) { @@ -23911,7 +23895,7 @@ onMouseClick: function(elm, data, i) { var array = prepareIOList(elm.__data__,"in") var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],array) - var title = "Here is a list" + var title = "List view of all inputs for " + elm.__data__.id + "; Categorization: " + data.description; showList(title,variables,nodeMenu) }, onMouseOver: function(elm,data,i){}}); @@ -23921,7 +23905,7 @@ onMouseClick: function(elm, data, i) { var array = prepareIOList(elm.__data__,"out") var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],array) - var title = "Here is a list" + var title = "List view of all outputs from " + elm.__data__.id + "; Categorization: " + data.description; showList(title,variables,nodeMenu) }, onMouseOver: function(elm,data,i){}}); @@ -25898,27 +25882,23 @@ //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) + function highlight(data) { - aText = "/"+data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - var allLinks = d3.selectAll(".link"); - var allLinks_tmp = allLinks[0]; - allLinks_tmp.forEach(function(p) { - var firstElement_tmp = p.__data__.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.__data__.name,text_fromFirst)) - { - d3.select(p).style("opacity", .8); - } - else - { - d3.select(p).style("opacity", 0); - } - }); - } + xPath = data.xPath; + var allLinks = d3.selectAll(".link"); + var allLinks_tmp = allLinks[0]; + allLinks_tmp.forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+xPath.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p).style("opacity", .8); + } + else + { + d3.select(p).style("opacity", 0); + } + }); } function showVariableTable(aVariable) @@ -25987,8 +25967,7 @@ onMouseDown: function(elm, d, i) { d3.selectAll(".treeFrame").attr("fill-opacity", .5); d3.selectAll(".nodeText").style("fill-opacity", 0.5); - var theText=""; - highlight(d,theText); + highlight(d); }, onMouseUp: function(elm, d, i) { d3.selectAll(".link").style("opacity",.6) @@ -26152,7 +26131,7 @@ onMouseClick: function(elm, data, i) { var variables = []; var pipeData = elm.__data__.name; - var title = "Here is a list" + var title = "List view of variable flow: " + elm.__data__.source.id + " → " + elm.__data__.target.id variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) prune_tree(pipeData,variables) variables.forEach(function(variable) @@ -26402,7 +26381,7 @@ { if (theLink.to == theNode.id) { - array = array + ", " + theLink.name; + array = array + "," + theLink.name; } name_tmp = "Input tree view:" + theNode.id + "; Categorization: " + categoryDescr; } @@ -26410,13 +26389,12 @@ { if (theLink.from == theNode.id) { - array = array + ", " + theLink.name; + array = array + "," + theLink.name; } name_tmp = "Output tree view:" + theNode.id + "; Categorization: " + categoryDescr; } }) - - var theSchema = currentGraph.variableSchemes[categoryID]; + var theSchema = JSON.parse(JSON.stringify(currentGraph.variableSchemes[categoryID])); createTreeLayout(name_tmp,theSchema,array,link,nodeMenu) } //############################################################ @@ -26451,11 +26429,11 @@ { if (theLink.to == elm.__data__.id) { - pipeData = pipeData + ", " + theLink.name; + pipeData = pipeData + "," + theLink.name; } }) - var title = "Here is a list" + var title = "List view of all inputs for " + elm.__data__.id + "; Categorization: " + data.description var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) prune_tree(pipeData,variables) variables.forEach(function(variable) @@ -26480,11 +26458,11 @@ { if (theLink.from == elm.__data__.id) { - pipeData = pipeData + ", " + theLink.name; + pipeData = pipeData + "," + theLink.name; } }) - var title = "Here is a list" + var title = "List view of all outputs from " + elm.__data_.id + "; Categorization: " + data.description var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) prune_tree(pipeData,variables) variables.forEach(function(variable) @@ -26719,7 +26697,7 @@ } } } - + // Call visit function to establish maxLabelLength visit(treeData, function(d) { totalNodes++; @@ -27395,27 +27373,23 @@ varCategories = entireData.categories; //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) + function highlight(data) { - aText = "/"+data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - var allLinks = d3.selectAll(".link"); - var allLinks_tmp = allLinks[0]; - allLinks_tmp.forEach(function(p) { - var firstElement_tmp = p.__data__.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.__data__.name,text_fromFirst)) - { - d3.select(p).style("opacity", .8); - } - else - { - d3.select(p).style("opacity", 0); - } - }); - } + var xPath = data.xPath; + var allLinks = d3.selectAll(".link"); + var allLinks_tmp = allLinks[0]; + allLinks_tmp.forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+xPath.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p).style("opacity", .8); + } + else + { + d3.select(p).style("opacity", 0); + } + }); } function showVariableTable(aVariable) @@ -27484,8 +27458,7 @@ onMouseDown: function(elm, d, i) { d3.selectAll(".treeFrame").attr("fill-opacity", .5); d3.selectAll(".nodeText").style("fill-opacity", 0.5); - var theText=""; - highlight(d,theText); + highlight(d); }, onMouseUp: function(elm, d, i) { d3.selectAll(".link").style("opacity",.6) @@ -27679,8 +27652,6 @@ .on("click", function() { var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); - - //aigner: HIER WEITER! evtl. treeData aufbauen (buildTree) um nodeMenu einfacher zu machen variables.forEach(function(variable) { variable.name = variable.xPath @@ -27688,7 +27659,7 @@ variable.data = variable variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] }) - var title = "Here is a list" + var title = "List view: full variable set categorized according to " + varCategories[this.id].description showList(title,variables,nodeMenu) }) } diff --git a/kadmos/vistoms/templates/VISTOMS_Static.html b/kadmos/vistoms/templates/VISTOMS_Static.html index 0e245abdec5df75a6f27423fbb16f405d103d70e..858822d3d800a75cf043513cd61d7549ae4a4e35 100644 --- a/kadmos/vistoms/templates/VISTOMS_Static.html +++ b/kadmos/vistoms/templates/VISTOMS_Static.html @@ -1970,13 +1970,22 @@ { acknowledgements(); }) - //########################################################## //aigner: make dropwdown section for the multiple MDO graphs tzhat can be visualized //########################################################## - var ul = d3.select("body").append("div").attr("class","navigationBarDiv").append("ul") + var navigationBarDiv = d3.select("body").append("div").attr("class","navigationBarDiv") + var ul = navigationBarDiv.append("ul") + navigationBarDiv.on("mouseover", function() + { + d3.select(this).style("z-index","1300"); + }) + .on("mouseout", function() + { + d3.select(this).style("z-index",""); + }) + function makeViewButtons(data,name, aView) { var dropdown1 = ul.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) @@ -2114,8 +2123,6 @@ //#####################################################################// function tutorial() { - - var theButtons = { cancel: { @@ -2164,6 +2171,7 @@ if (!d3.select(".xdsmDiv").empty()) { + bootbox.hideAll(); var dialog = bootbox.dialog( { title: 'XDSM View', @@ -2180,6 +2188,7 @@ } else if(!d3.select(".edgeBundlesDiv").empty()) { + bootbox.hideAll(); var dialog = bootbox.dialog({ title: 'Edge Bundles View', message: "<p><b>To interactively inspect the MDO system there are several options.</b></p>" @@ -2196,6 +2205,7 @@ } else if(!d3.select(".sankeyDiagramDiv").empty()) { + bootbox.hideAll(); var dialog = bootbox.dialog({ title: 'Sankey Diagram', message: "<p><b>To interactively inspect the MDO system there are several options.</b></p>" @@ -19950,6 +19960,157 @@ //#####################################################################// function startXDSM(data, graphID) { + + //Highlight function, that shows usage of a node in the XDSM + function highlight(data,aText) + { + aText = "/"+data.data.name+aText; + if (data.parent){highlight(data.parent,aText)} + else + { + scenarioKeys.forEach(function(k) + { + var xdsm_tmp; + xdsm_tmp = xdsms[k]; + if (xdsm_tmp) + { + xdsm_tmp.svg.selectAll(".edge").each(function(p) + { + var firstElement_tmp = p.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] + if (include(p.name,text_fromFirst)) + { + var highlightEdge = d3.select(this).select("polygon"); + highlightEdge + .style("stroke-width",5.) + .style("stroke","#CC0000") + d3.selectAll(".treeFrame") + .attr("fill-opacity", 0.5) + .attr("stroke-opacity", 0.5); + d3.selectAll(".nodeText").style("fill-opacity",0.5); + } + }) + } + }) + } + } + + //Unhighlight function again + function unhighlight(data,aText) + { + aText = "/"+data.data.name+aText; + if (data.parent){unhighlight(data.parent,aText)} + else + { + scenarioKeys.forEach(function(k) + { + var xdsm_tmp; + xdsm_tmp = xdsms[k]; + if (xdsm_tmp) + { + xdsm_tmp.svg.selectAll(".edge").each(function(p) + { + var firstElement_tmp = p.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] + if (include(p.name,text_fromFirst)) + { + var highlightEdge = d3.select(this).select("polygon"); + highlightEdge + .style("stroke-width",1.) + .style("stroke","black"); + d3.selectAll(".treeFrame") + .attr("fill-opacity", 0.8) + .attr("stroke-opacity", 0.8); + d3.selectAll(".nodeText").style("fill-opacity",1); + } + }) + } + }) + } + } + + + function showVariableTable(aVariable) + { + var headLine = "Node Information (" + aVariable.data.name + ")"; + var data = []; + // render the table(s) + data.push({ "name" : "Name", "value" : "\""+aVariable.data.name+"\"" }) + data.push({ "name" : "xPath", "value" : aVariable.data.xPath }) + if (aVariable.data.type){data.push({ "name" : "Type", "value" : aVariable.data.type })} + if (aVariable.data.level){data.push({ "name" : "Level", "value" : aVariable.data.level })} + if (aVariable.data.children){data.push({ "name" : "Number of children", "value" : aVariable.data.children.length })} + if (aVariable.data.dimension){data.push({ "name" : "Dimension", "value" : aVariable.data.dimension })} + else if(aVariable.data.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} + if (aVariable.data.value){data.push({ "name" : "Value(s)", "value" : aVariable.data.value })} + + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(headLine) + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + data.forEach(function(listElement) + { + var row = listGroup.append("tr") + row.append("td").text(listElement.name) + row.append("td").text(listElement.value) + + }) + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + } + //menu --> functions for right click options + var nodeMenu = [ + { + title: 'Show node information', + onMouseDown: function(elm, d, i) { + showVariableTable(d); + }, + onMouseUp: function(elm, d, i) {}, + onMouseOver: function(elm, d, i) {}, + childrenItems: [] + }, + { + title: 'Show usage of node in XDSM', + onMouseDown: function(elm, d, i) { + var theText=""; + highlight(d,theText); + }, + onMouseUp: function(elm, d, i) { + var theText=""; + unhighlight(d,theText); + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Copy x-path to clipboard', + onMouseDown: function(elm, d, i) { + window.prompt("Copy to clipboard: Ctrl+C, Enter", d.data.xPath); + d3.select('.d3-context-menu').style('display', 'none'); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }] + var graphs, currentGraph, varCategories, entireData; entireData = data; @@ -19988,7 +20149,49 @@ .text("Graph description: " + currentGraph.description) //################################################################################################// - + function showList(aTitle,aList,aMenu) + { + if (aList.length != 0) + { + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(aTitle) + panel_div.append("input") + .attr("id","myInput") + .attr("placeholder","Filter search...") + .attr("title","Type in a name") + .attr("onkeyup","filterSearch()") + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + var tr = listGroup + .selectAll('tr') + .data(aList).enter() + .append('tr') + var td = tr.append("td").html(function(d) { + if (d.xPath){return d.xPath;} + else {return d.name;} + }) + tr.on('contextmenu', d3.contextMenu(aMenu)); + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + $('.myPanel').lobiPanel('height','5000'); + } + } + //aigner: Data Model Expand Button //#################################################################################################################### var dataModelDiv = d3.select(".xdsmDiv").append("div").attr("class","dataModelDiv").attr("transform","translate(10,0)") @@ -20002,8 +20205,10 @@ .style("margin-bottom","0px") .attr("height","20") .attr("width","20") - dropdown1.append("a").text("Data Model") + dropdown1.append("a").text("Data Model Tree") var links = dropdown1.append("ul"); + var xOffset_ul = dropdown1._groups[0][0].offsetLeft+dropdown1._groups[0][0].offsetWidth-40; + links.style("left", String(xOffset_ul)+"px") for (var j=0; j< varCategories.length; j++) { //console.log(varCategories[j]) @@ -20018,7 +20223,48 @@ }) } //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works - dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") + //dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") + //#################################################################################################################### + + //aigner: Data Model List View Button + //#################################################################################################################### + var ul_list = dataModelDiv.append("ul") + var dropdownList = ul_list.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) + dropdownList.append("img").attr("src",fileReference.AGILE_Icon) + .attr("align","left") + .style("margin-left","6px") + .style("margin-right","-10px") + .style("margin-top","10px") + .style("margin-bottom","0px") + .attr("height","20") + .attr("width","20") + dropdownList.append("a").text("Data Model List") + var linksList = dropdownList.append("ul"); + var xOffset_ul = dropdownList._groups[0][0].offsetLeft+dropdownList._groups[0][0].offsetWidth-40; + linksList.style("left", String(xOffset_ul)+"px") + for (var j=0; j< varCategories.length; j++) + { + //console.log(varCategories[j]) + var linkLi = linksList.append("li"); + var linkA = linkLi.append("a") + .attr("id",j) + .text(varCategories[j].description) + .on("mouseover", function(){d3.select(this).style("cursor", "pointer")}) + .on("click", function() + { + var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + var title = "List view: full variable set categorized according to " + varCategories[this.id].description + showList(title,variables,nodeMenu) + }) + } + //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works //#################################################################################################################### @@ -20123,34 +20369,34 @@ xdsm.svg.selectAll(".node") - .each(function(d) + .each(function(node) { var gNode = this; var d3gNode = d3.select(gNode); //aigner: Creation of input/output tree //############################################################ - function showIOTree(aCategory, categoryDescr, k, io) - { + function showIOTree(aCategory, categoryDescr, aNode, io) + { var edges = d3.selectAll(".edge"); var array=""; var name; - edges.each(function(d) + edges.each(function(edge) { if (io=="in") { - name = "Input tree view: " + k.id + "; Categorization: " + categoryDescr; - if (d.to == k.id) + name = "Input tree view: " + aNode.id + "; Categorization: " + categoryDescr; + if (edge.to == aNode.id) { - array = array + "," + d.name; + array = array + "," + edge.name; } } else if (io=="out") { - name = "Output tree view:" + k.id + "; Categorization: " + categoryDescr; - if (d.from == k.id) + name = "Output tree view:" + aNode.id + "; Categorization: " + categoryDescr; + if (edge.from == aNode.id) { - array = array + "," + d.name; + array = array + "," + edge.name; } } }) @@ -20181,20 +20427,80 @@ maketreeLayout(array, treeLayout, treeLayoutSVG, treeLayoutdiv, divClassName, headLine, aCategory); } //############################################################ + + //aigner: Creation of input/output list + //############################################################ + function showIOList(aCategory, categoryDescr, aNode, io) + { + var edges = d3.selectAll(".edge"); + var array=""; + var title; + edges.each(function(edge) + { + if (io=="in") + { + title = "List view of all inputs for " + aNode.id + "; Categorization: " + categoryDescr; + if (edge.to == aNode.id) + { + array = array + "," + edge.name; + } + } + else if (io=="out") + { + title = "List view of all outputs for " + aNode.id + "; Categorization: " + categoryDescr; + if (edge.from == aNode.id) + { + array = array + "," + edge.name; + } + } + }) + + var variables = []; + var pipeData = array; + variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[aCategory])) + prune_tree(pipeData,variables) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + + } + //############################################################ - var inputChildrenitems = []; - var outputChildrenitems = []; + var inputChildrenitemsTree = []; + var outputChildrenitemsTree = []; + for (var j=0; j< varCategories.length; j++) + { + inputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,node,"in")}, + onMouseOver: function(elm,data,i){}}); + outputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,node,"out")}, + onMouseOver: function(elm,data,i){}}); + } + + var inputChildrenitemsList = []; + var outputChildrenitemsList = []; for (var j=0; j< varCategories.length; j++) { - inputChildrenitems.push({title: 'according to ' + varCategories[j].description, + inputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, - onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,d,"in")}, + onMouseClick: function(elm, data, i) {showIOList(data.varCategory,data.description,node,"out")}, onMouseOver: function(elm,data,i){}}); - outputChildrenitems.push({title: 'according to ' + varCategories[j].description, + outputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, - onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,d,"out")}, + onMouseClick: function(elm, data, i) {showIOList(data.varCategory,data.description,node,"out")}, onMouseOver: function(elm,data,i){}}); } @@ -20287,7 +20593,7 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: inputChildrenitems + childrenItems: inputChildrenitemsTree }, { title: 'Show output variable tree...', @@ -20297,13 +20603,33 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: outputChildrenitems + childrenItems: outputChildrenitemsTree + }, + { + title: 'Show input variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: inputChildrenitemsList + }, + { + title: 'Show output variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: outputChildrenitemsList } ] scenarioKeys.forEach(function(k) { - if (k == d.xdsm) + if (k == node.xdsm) { var cx, cy; for (var j=0; j < gNode.childNodes.length; j++) @@ -20374,7 +20700,6 @@ d3gNode.append("svg:title").text("Click right to inspect"); d3gNode = d3gNode.on('mouseover', function(){d3.select(this).style("cursor", "pointer")}); d3gNode = d3gNode.on('contextmenu', d3.contextMenu(toolMenu)) - }) function prepareTreeLayout(xdsms, refName) @@ -20476,24 +20801,48 @@ } xdsms[refName].svg.selectAll(".edge") - .each(function(d) + .each(function(edge) { //edgeMenu --> functions for right click options - var edgeChildrenItems = []; + var edgeChildrenItemsTree = []; for (var j=0; j< varCategories.length; j++) { - edgeChildrenItems.push({title: 'according to ' + varCategories[j].description, + edgeChildrenItemsTree.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, - onMouseClick: function(elm, data, i) {showEdgeTree(d,data.varCategory,data.description)}, + onMouseClick: function(elm, data, i) {showEdgeTree(edge,data.varCategory,data.description)}, onMouseOver: function(elm,data,i){}}); } + var edgeChildrenItemsList = []; + for (var j=0; j< varCategories.length; j++) + { + edgeChildrenItemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var variables = []; + var pipeData = edge.name; + var title = "List view: " + edge.from + " → " + edge.to + "; Categorization: " + data.description; + variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) + prune_tree(pipeData,variables) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + }, + onMouseOver: function(elm,data,i){}}); + } var theEdge = this; var edgeMenu = [ { title: 'Show edge info', onMouseDown: function(elm, k, i) { - showEdgeTable(d) + showEdgeTable(edge) }, onMouseUp: function(elm, k, i) { }, @@ -20509,7 +20858,28 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: edgeChildrenItems + childrenItems: edgeChildrenItemsTree + }, + { + title: 'Show variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: edgeChildrenItemsList + }, + { + title: 'Delete a variable connection here...', + onMouseDown: function(elm, k, i) { + deleteEdge(k) + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: {} } ] @@ -20763,7 +21133,6 @@ newWidth=Math.max(newWidth,getTextWidth(aName,"Arial 12pt")); //aigner: Adjust height and width of the frame - console.log(aLobiID) $('.' + aLobiID).lobiPanel('setWidth', newWidth + margin.top + margin.bottom +400+maxLabelLength*25+offset_tmp); $('.' + aLobiID).lobiPanel('setHeight', newHeight + margin.top + 2*margin.bottom+offset_tmp); div = div.attr("height", newHeight + margin.top + margin.bottom+offset_tmp) @@ -20849,238 +21218,6 @@ //.text(function(d) { return d.data.text; }); - //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) - { - aText = "/"+data.data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - scenarioKeys.forEach(function(k) - { - var xdsm_tmp; - xdsm_tmp = xdsms[k]; - if (xdsm_tmp) - { - xdsm_tmp.svg.selectAll(".edge").each(function(p) - { - var firstElement_tmp = p.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.name,text_fromFirst)) - { - var highlightEdge = d3.select(this).select("polygon"); - highlightEdge - .style("stroke-width",5.) - .style("stroke","#CC0000") - d3.selectAll(".treeFrame") - .attr("fill-opacity", 0.5) - .attr("stroke-opacity", 0.5); - d3.selectAll(".nodeText").style("fill-opacity",0.5); - } - }) - } - }) - } - } - - //Unhighlight function again - function unhighlight(data,aText) - { - aText = "/"+data.data.name+aText; - if (data.parent){unhighlight(data.parent,aText)} - else - { - scenarioKeys.forEach(function(k) - { - var xdsm_tmp; - xdsm_tmp = xdsms[k]; - if (xdsm_tmp) - { - xdsm_tmp.svg.selectAll(".edge").each(function(p) - { - var firstElement_tmp = p.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.name,text_fromFirst)) - { - var highlightEdge = d3.select(this).select("polygon"); - highlightEdge - .style("stroke-width",1.) - .style("stroke","black"); - d3.selectAll(".treeFrame") - .attr("fill-opacity", 0.8) - .attr("stroke-opacity", 0.8); - d3.selectAll(".nodeText").style("fill-opacity",1); - } - }) - } - }) - } - } - - - function showVariableTable(aVariable) - { - var headLine = "Node Information (" + aVariable.data.name + ")"; - var data = []; - // render the table(s) - data.push({ "name" : "Name", "value" : "\""+aVariable.data.name+"\"" }) - data.push({ "name" : "xPath", "value" : aVariable.data.xPath }) - if (aVariable.data.type){data.push({ "name" : "Type", "value" : aVariable.data.type })} - if (aVariable.data.level){data.push({ "name" : "Level", "value" : aVariable.data.level })} - if (aVariable.data.children){data.push({ "name" : "Number of children", "value" : aVariable.data.children.length })} - if (aVariable.data.dimension){data.push({ "name" : "Dimension", "value" : aVariable.data.dimension })} - else if(aVariable.data.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} - if (aVariable.data.value){data.push({ "name" : "Value(s)", "value" : aVariable.data.value })} - - var d3_body = d3.select("body"); - - var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") - panel_div.append("div").attr("class","panel-heading") - .append("div").attr("class","panel_title").append("h4").text(headLine) - var listGroup = panel_div.append("div").attr("class","panel-body") - .append("table").attr("id","myTable") - .append("tbody") - - data.forEach(function(listElement) - { - var row = listGroup.append("tr") - row.append("td").text(listElement.name) - row.append("td").text(listElement.value) - - }) - $('.myPanel').lobiPanel({ - reload: false, - editTitle: false, - expand: false, - unpin: false, - resize: "none", - minWidth: 200, - minHeight: 200, - maxWidth: 1100, - maxHeight: 1200, - }); - $('.myPanel').lobiPanel('unpin'); - } - - - // Function to download data to a file - function download(filename, text) { - var element = document.createElement('a'); - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); - element.setAttribute('download', filename); - - element.style.display = 'none'; - document.body.appendChild(element); - - element.click(); - - document.body.removeChild(element); - } - - //menu --> functions for right click options - var nodeMenu = [ - { - title: 'Show node information', - onMouseDown: function(elm, d, i) { - showVariableTable(d); - }, - onMouseUp: function(elm, d, i) {}, - onMouseOver: function(elm, d, i) {}, - childrenItems: [] - }, - { - title: 'Show usage of node in XDSM', - onMouseDown: function(elm, d, i) { - var theText=""; - highlight(d,theText); - }, - onMouseUp: function(elm, d, i) { - var theText=""; - unhighlight(d,theText); - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Copy x-path to clipboard', - onMouseDown: function(elm, d, i) { - function copyToClipboard(text) - { - window.prompt("Copy to clipboard: Ctrl+C, Enter", text); - } - function copyXPathToClipboard(data,aText) - { - aText = "/"+data.data.name+aText; - if (data.parent){copyXPathToClipboard(data.parent,aText)} - else{copyToClipboard(aText);} - } - var copyText=""; - copyXPathToClipboard(d,copyText); - d3.select('.d3-context-menu').style('display', 'none'); - }, - onMouseUp: function(elm, d, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Download full tree as XML-file', - onMouseDown: function(elm, d, i) { - //Begin xml structure with the first element - var xmlString = "<"+nodes[0].data.name+">"+"</"+nodes[0].data.name+">"; - //Create a new xml document - var parser = new DOMParser(); - var xmlDocument = parser.parseFromString(xmlString, "text/xml"); //important to use "text/xml" - //Get initial xPath of the tree and pass it to the function "writeTreeToXML" - var initialXPath = "/"+nodes[0].data.name; - writeTreeToXML(nodes[0],xmlDocument,initialXPath); - //remove all attributes dummyID - removeAttributeInAllElements(xmlDocument,'dummyID'); - //Make the xml document a string - var serializer = new XMLSerializer(); - var xmlString = serializer.serializeToString(xmlDocument); - xmlString = vkbeautify.xml(xmlString); - //Download a document with the xml-schema - download(aName+'_full.xml',xmlString); - }, - onMouseUp: function(elm, d, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Download tree as XML-file from current node', - onMouseDown: function(elm, d, i) { - var xmlString = putAncestorsInXMLString({ val : '' }, d).val; - var initialXPath = putAncestorsInXPath({ val : '' }, d).val; - //Create a new xml document - var parser = new DOMParser(); - var xmlDocument = parser.parseFromString(xmlString, "text/xml"); //important to use "text/xml" - //Get initial xPath of the tree and pass it to the function "writeCurrentTreeToXML" - writeTreeToXML(d,xmlDocument,initialXPath); - //remove all attributes dummyID - removeAttributeInAllElements(xmlDocument,'dummyID'); - //Make the xml document a string - var serializer = new XMLSerializer(); - xmlString = serializer.serializeToString(xmlDocument); - xmlString = vkbeautify.xml(xmlString); - //Download a document with the xml-schema - download(aName+"_"+d.data.name+'.xml',xmlString); - }, - onMouseUp: function(elm, d, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - } - ] - - - - //Function writeTreeToXML goes through tree nodes and puts the into an xml document function writeTreeToXML(aNode,anXMLDoc,anXPath) { @@ -21229,10 +21366,68 @@ return strWrapper; } } - - nodeEnter = nodeEnter - .on('contextmenu', d3.contextMenu(nodeMenu)); - + + var nodeTreeMenu = nodeMenu; + var treeMenu = [ + { + title: 'Download full tree as XML-file', + onMouseDown: function(elm, d, i) { + //Begin xml structure with the first element + var xmlString = "<"+nodes[0].data.name+">"+"</"+nodes[0].data.name+">"; + //Create a new xml document + var parser = new DOMParser(); + var xmlDocument = parser.parseFromString(xmlString, "text/xml"); //important to use "text/xml" + //Get initial xPath of the tree and pass it to the function "writeTreeToXML" + var initialXPath = "/"+nodes[0].data.name; + writeTreeToXML(nodes[0],xmlDocument,initialXPath); + //remove all attributes dummyID + removeAttributeInAllElements(xmlDocument,'dummyID'); + //Make the xml document a string + var serializer = new XMLSerializer(); + var xmlString = serializer.serializeToString(xmlDocument); + xmlString = vkbeautify.xml(xmlString); + //Download a document with the xml-schema + download(aName+'_full.xml',xmlString); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Download tree as XML-file from current node', + onMouseDown: function(elm, d, i) { + var xmlString = putAncestorsInXMLString({ val : '' }, d).val; + var initialXPath = putAncestorsInXPath({ val : '' }, d).val; + //Create a new xml document + var parser = new DOMParser(); + var xmlDocument = parser.parseFromString(xmlString, "text/xml"); //important to use "text/xml" + //Get initial xPath of the tree and pass it to the function "writeCurrentTreeToXML" + writeTreeToXML(d,xmlDocument,initialXPath); + //remove all attributes dummyID + removeAttributeInAllElements(xmlDocument,'dummyID'); + //Make the xml document a string + var serializer = new XMLSerializer(); + xmlString = serializer.serializeToString(xmlDocument); + xmlString = vkbeautify.xml(xmlString); + //Download a document with the xml-schema + download(aName+"_"+d.data.name+'.xml',xmlString); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + } + ] + var nodeTreeMenu = nodeMenu.concat(treeMenu); + + + + nodeEnter = nodeEnter + .on('contextmenu', d3.contextMenu(nodeTreeMenu)); + nodeEnter.append("svg:title").text("Click left to expand, click right to inspect") @@ -21323,7 +21518,7 @@ } startXDSM(data,graphID); - ////aigner: Unused funcktions --> Could be helpful at some point + ////aigner: Unused functions --> Could be helpful at some point ////aigner: clone function, so that original object is not overwritten but deep copied // function clone(obj) { // if (null == obj || "object" != typeof obj) return obj; @@ -21581,7 +21776,317 @@ varCategories = entireData.categories; var classes = currentGraph.edgeBundles; - + //Highlight function, that shows usage of a node in the XDSM + function highlight(data,aText) + { + aText = "/"+data.name+aText; + if (data.parent){highlight(data.parent,aText)} + else + { + var allLinks = d3.selectAll(".edgeBundlesLink"); + allLinks[0].forEach(function(aLink) + { + + aLink.__data__.pipeData_in = aLink.__data__.source.pipeline_data[aLink.__data__.target.name]; + aLink.__data__.pipeData_out = aLink.__data__.target.pipeline_data[aLink.__data__.source.name]; + aLink.__data__.pipeDataName_in = ""; + aLink.__data__.pipeDataName_out = ""; + aLink.__data__.name = ""; + if (aLink.__data__.pipeData_in) + { + for (var i=0; i<aLink.__data__.pipeData_in.length; i++) + { + if (i==0){aLink.__data__.pipeDataName_in += aLink.__data__.pipeData_in[i];} + else{aLink.__data__.pipeDataName_in += "," + aLink.__data__.pipeData_in[i];} + + } + aLink.__data__.name += aLink.__data__.pipeDataName_in + } + if (aLink.__data__.pipeData_out) + { + for (var i=0; i<aLink.__data__.pipeData_out.length; i++) + { + if (i==0){aLink.__data__.pipeDataName_out += aLink.__data__.pipeData_out[i];} + else{aLink.__data__.pipeDataName_out += "," + aLink.__data__.pipeData_out[i];} + } + aLink.__data__.name += aLink.__data__.pipeDataName_out + } + }) + + //var allLinks_tmp = allLinks[0]; + allLinks[0].forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p) + .style("stroke-opacity", 1.0) + } + else + { + d3.select(p).style("stroke-opacity", 0); + } + }); + } + } + + //Function writeTreeToXML goes through tree nodes and puts the into an xml document + function writeTreeToXML(aNode,anXMLDoc,anXPath) + { + //Variable "children" + //--> One children variable, no matter whether a node has "_children" (collapsed) or "children" (expanded) + var children; + if (aNode._children){children = aNode._children;} + else if (aNode.children){children = aNode.children;} + + //Get current xml element with its xPath + var element = anXMLDoc.evaluate(anXPath,anXMLDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; + if (element != null) {element.value = '...';} + + //If a node has children (collapsed or expanded), loop through them + if (children) + { + for (var i=0; i < children.length;i++) + { + //Name of the new XML element --> childName + var child = children[i]; + var childName = child.name.split(/[\[\]]+/);//Split childName at "[]" which is the uID + var cleanChildName = childName[0].split(/[\+\*\^\-\ \#]+/);//Split childName all special characters + var newNode = anXMLDoc.createElement(String(cleanChildName[0])); + + //The children are appended to the xPath --> newXPath + var newXPath = anXPath+"/"+cleanChildName[0]; + + //If childName contains a uID, make the uID an attribute + if (childName[1]) + { + if (parseInt(childName[1])) + { + var dummyID = childName[1]; + newNode.setAttribute("dummyID", dummyID) + newXPath = newXPath+"[@dummyID='"+dummyID+"']"; + } + else + { + var uID = childName[1]; + newNode.setAttribute("uID", uID) + newXPath = newXPath+"[@uID='"+uID+"']"; + } + } + if (cleanChildName.length>1) {newNode.setAttribute("elementName", childName[0])}; + + //Append the newNode to the xml structure + element.appendChild(newNode); + + + + ////aigner: Sorting of XML elements according to "uID" + // var items = element.children; + // var itemsArr = []; + // for (var j in items) { + // if (items[j].nodeType == 1) { // get rid of the whitespace text nodes + // itemsArr.push(items[j]); + // } + // } + // itemsArr.sort(function(a,b){ + // if (a.getAttribute("uID") < b.getAttribute("uID")) + // return -1; + // if (a.getAttribute("uID") > b.getAttribute("uID")) + // return 1; + // return 0; + // }); + + // for (j = 0; j < itemsArr.length; ++j) { + // element.appendChild(itemsArr[j]); + // } + + //call function writeTreeToXML recursively for all children + writeTreeToXML(child,anXMLDoc,newXPath) + } + } + else + { + if (aNode.value){element.innerHTML = String(aNode.value);} + else{element.innerHTML = " ";} + } + //return the xml document + return anXMLDoc; + } + + function removeAttributeInAllElements(aDocument,attribute) + { + var matchingElements = []; + var allElements = aDocument.getElementsByTagName('*'); + for (var i = 0, n = allElements.length; i < n; i++) + { + if (allElements[i].getAttribute(attribute) !== null) + { + allElements[i].removeAttribute(attribute); + } + } + return matchingElements; + } + + function putAncestorsInXMLString(strWrapper, aNode) + { + //Name of the new XML element + var nodeName = aNode.name.split(/[\[\]]+/);//Split name at "[]" which is the uID + var cleanNodeName = nodeName[0].split(/[\+\*\^\-\ \#]+/);//Split nodeName all special characters + //If nodeName contains a uID, make the uID an attribute + if (nodeName[1]) + { + var uID = nodeName[1]; + strWrapper.val = "<"+cleanNodeName[0]+" uID='"+ uID +"'>"+strWrapper.val+"</"+cleanNodeName[0]+">";; + } + else + { + strWrapper.val = "<"+cleanNodeName[0]+">"+strWrapper.val+"</"+cleanNodeName[0]+">";; + } + var aParent = aNode.parent; + if (aParent) + { + return putAncestorsInXMLString(strWrapper, aParent); + } + else + { + return strWrapper; + } + } + + function putAncestorsInXPath(strWrapper, aNode) + { + //Name of the new XML element + var nodeName = aNode.name.split(/[\[\]]+/);//Split name at "[]" which is the uID + var cleanNodeName = nodeName[0].split(/[\+\*\^\-\ \#]+/);//Split nodeName all special characters + //If nodeName contains a uID, make the uID an attribute + if (nodeName[1]) + { + var uID = nodeName[1]; + strWrapper.val = "/"+cleanNodeName[0]+"[@uID='"+uID+"']"+strWrapper.val; + } + else + { + strWrapper.val = "/"+cleanNodeName[0]+strWrapper.val; + } + var aParent = aNode.parent; + if (aParent) + { + return putAncestorsInXPath(strWrapper, aParent); + } + else + { + return strWrapper; + } + } + + // Function to download data to a file + function download(filename, text) { + var element = document.createElement('a'); + element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); + element.setAttribute('download', filename); + + element.style.display = 'none'; + document.body.appendChild(element); + + element.click(); + + document.body.removeChild(element); + } + + function showVariableTable(aVariable) + { + + var headLine = "Node Information (" + aVariable.name + ")"; + var data = []; + // render the table(s) + data.push({ "name" : "Name", "value" : "\""+aVariable.name+"\"" }) + data.push({ "name" : "xPath", "value" : aVariable.xPath }) + if (aVariable.type){data.push({ "name" : "Type", "value" : aVariable.type })} + if (aVariable.level){data.push({ "name" : "Level", "value" : aVariable.level })} + if (aVariable.children || aVariable._children) + { + var childrenNum=0; + if (aVariable.children){childrenNum=childrenNum+aVariable.children.length} + if (aVariable._children){childrenNum=childrenNum+aVariable._children.length} + data.push({ "name" : "Number of children", "value" : childrenNum }) + } + if (aVariable.dimension){data.push({ "name" : "Dimension", "value" : aVariable.dimension })} + else if(aVariable.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} + if (aVariable.value){data.push({ "name" : "Value(s)", "value" : aVariable.value })} + + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(headLine) + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + data.forEach(function(listElement) + { + var row = listGroup.append("tr") + row.append("td").text(listElement.name) + row.append("td").text(listElement.value) + + }) + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + } + + //menu --> functions for right click options + var nodeMenu = [ + { + title: 'Show node information', + onMouseDown: function(elm, d, i) { + showVariableTable(d); + }, + onMouseUp: function(elm, d, i) {}, + onMouseOver: function(elm, d, i) {}, + childrenItems: [] + }, + { + title: 'Show usage of node in diagram', + onMouseDown: function(elm, d, i) { + d3.selectAll(".treeFrame").attr("fill-opacity", .5); + d3.selectAll(".nodeText").style("fill-opacity", 0.5); + var theText=""; + highlight(d,theText); + }, + onMouseUp: function(elm, d, i) { + d3.selectAll(".edgeBundlesLink") + .style("stroke-opacity",.4) + d3.selectAll(".treeFrame").attr("fill-opacity", .8); + d3.selectAll(".nodeText").style("fill-opacity", 1); + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Copy x-path to clipboard', + onMouseDown: function(elm, d, i) { + window.prompt("Copy to clipboard: Ctrl+C, Enter", d.xPath); + d3.select('.d3-context-menu').style('display', 'none'); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + } + ] + //################################################################################################// var headerDiv = d3.select(".edgeBundlesDiv").append("div").attr("class","panel panel-primary") headerDiv.append("div").attr("class","panel-heading text-center") @@ -21611,7 +22116,7 @@ var emptyArray=""; var allLinks = d3.selectAll(".edgeBundlesLink"); var theSchema = currentGraph.variableSchemes[categoryID]; - createTreeLayout(name_tmp,theSchema,emptyArray,allLinks); + createTreeLayout(name_tmp,theSchema,emptyArray,allLinks,nodeMenu); } var childrenItems = []; @@ -21635,13 +22140,54 @@ childrenItems: childrenItems } ] - //#####################################################################// - //aigner: treeLayout in the bottom - //################################################################################################// - //aigner: Data Model Expand Button - //########################################################## + + + function showList(aTitle,aList,aMenu) + { + if (aList.length != 0) + { + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(aTitle) + panel_div.append("input") + .attr("id","myInput") + .attr("placeholder","Filter search...") + .attr("title","Type in a name") + .attr("onkeyup","filterSearch()") + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + var tr = listGroup + .selectAll('tr') + .data(aList).enter() + .append('tr') + var td = tr.append("td").html(function(d) { + if (d.xPath){return d.xPath;} + else {return d.name;} + }) + tr.on('contextmenu', d3.contextMenu(aMenu)); + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + $('.myPanel').lobiPanel('height','5000'); + } + } + + //aigner: Data Model Tree View Button + //#################################################################################################################### var dataModelDiv = d3.select(".edgeBundlesDiv").append("div").attr("class","dataModelDiv").attr("transform","translate(10,0)") - dataModelDiv.append("svg:title").text("Click right to inspect") var ul = dataModelDiv.append("ul") var dropdown1 = ul.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) dropdown1.append("img").attr("src",fileReference.AGILE_Icon) @@ -21652,8 +22198,10 @@ .style("margin-bottom","0px") .attr("height","20") .attr("width","20") - dropdown1.append("a").text("Data Model") + dropdown1.append("a").text("Data Model Tree") var links = dropdown1.append("ul"); + var xOffset_ul = dropdown1[0][0].offsetLeft+dropdown1[0][0].offsetWidth-40; + links.style("left", String(xOffset_ul)+"px") for (var j=0; j< varCategories.length; j++) { //console.log(varCategories[j]) @@ -21666,12 +22214,51 @@ { showFullTree(varCategories[this.id].name,varCategories[this.id].description) }) - } //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works - dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") - //########################################################## - //################################################################################################// + //dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") + //#################################################################################################################### + + //aigner: Data Model List View Button + //#################################################################################################################### + var ul_list = dataModelDiv.append("ul") + var dropdownList = ul_list.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) + dropdownList.append("img").attr("src",fileReference.AGILE_Icon) + .attr("align","left") + .style("margin-left","6px") + .style("margin-right","-10px") + .style("margin-top","10px") + .style("margin-bottom","0px") + .attr("height","20") + .attr("width","20") + dropdownList.append("a").text("Data Model List") + var linksList = dropdownList.append("ul"); + var xOffset_ul = dropdownList[0][0].offsetLeft+dropdownList[0][0].offsetWidth-40; + linksList.style("left", String(xOffset_ul)+"px") + for (var j=0; j< varCategories.length; j++) + { + //console.log(varCategories[j]) + var linkLi = linksList.append("li"); + var linkA = linkLi.append("a") + .attr("id",j) + .text(varCategories[j].description) + .on("mouseover", function(){d3.select(this).style("cursor", "pointer")}) + .on("click", function() + { + var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + var title = "List view: full variable set categorized according to " + varCategories[this.id].description + showList(title,variables,nodeMenu) + }) + } + //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works + //#################################################################################################################### //aigner: legend @@ -21728,6 +22315,7 @@ //d3.select(".legendDiv").moveToBack() d3.select(".dataModelDiv").moveToBack() headerDiv.moveToBack() + d3.select(".addButtonDiv").moveToBack() d3.select(".navigationBarDiv").moveToBack() d3.select(".visPackDiv").moveToBack() @@ -21784,7 +22372,7 @@ { var theSchema = currentGraph.variableSchemes[aVarCategory]; var name_tmp = "Variable flow: " + aLink.__data__.source.name + " → " + aLink.__data__.target.name + "; Categorization: " + aCategoryDescr; - createTreeLayout(name_tmp,theSchema,aLink.__data__,link); + createTreeLayout(name_tmp,theSchema,aLink.__data__,link,nodeMenu); } function showEdgeTable(aLink) @@ -21894,21 +22482,43 @@ minWidth: 200, minHeight: 200, maxWidth: 1100, - maxHeight: 1100, + maxHeight: 1200, }); $('.myPanel').lobiPanel('unpin'); } //linkMenu --> functions for right click options - var linkChildrenItems = []; + var linkChildrenItemsTree = []; for (var j=0; j< varCategories.length; j++) { - linkChildrenItems.push({title: 'according to ' + varCategories[j].description, + linkChildrenItemsTree.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, onMouseClick: function(elm, data, i) {showLinkTree(elm,data.varCategory,data.description)}, onMouseOver: function(elm,data,i){}}); } + var linkChildrenItemsList = []; + for (var j=0; j< varCategories.length; j++) + { + linkChildrenItemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var title = "List view of variable flow: " + elm.__data__.source.id + " → " + elm.__data__.target.id + "; Categorization: " + data.description; + var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],elm.__data__) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + }, + onMouseOver: function(elm,data,i){}}); + } + var linkMenu = [ { title: 'Show edge info', @@ -21929,7 +22539,17 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: linkChildrenItems + childrenItems: linkChildrenItemsTree + }, + { + title: 'Show variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: linkChildrenItemsList } ] invisibleLink.append("svg:title").text("Click right to inspect") @@ -22046,7 +22666,7 @@ minWidth: 200, minHeight: 200, maxWidth: 1100, - maxHeight: 1100, + maxHeight: 1200, }); $('.myPanel').lobiPanel('unpin'); } @@ -22132,64 +22752,187 @@ } }) var theSchema = currentGraph.variableSchemes[categoryName] - createTreeLayout(name_tmp,theSchema,array,link) + createTreeLayout(name_tmp,theSchema,array,link,nodeMenu) } //############################################################ - - var inputChildrenitems = []; - var outputChildrenitems = []; - var inputChildrenitems = []; - var outputChildrenitems = []; - for (var j=0; j< varCategories.length; j++) - { - inputChildrenitems.push({title: 'according to ' + varCategories[j].description, - varCategory: varCategories[j].name, - description: varCategories[j].description, - onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"in")}, - onMouseOver: function(elm,data,i){}}); - outputChildrenitems.push({title: 'according to ' + varCategories[j].description, - varCategory: varCategories[j].name, - description: varCategories[j].description, - onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"out")}, - onMouseOver: function(elm,data,i){}}); - } - //menu --> functions for right click options - var toolMenu = [ - { - title: 'Show competence info', - onMouseDown: function(elm, k, i) { - showToolTable(k); - }, - onMouseUp: function(elm, k, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Show input variable tree...', - onMouseDown: function(elm, k, i) { - }, - onMouseUp: function(elm, k, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: inputChildrenitems - }, - { - title: 'Show output variable tree...', - onMouseDown: function(elm, k, i) { - }, - onMouseUp: function(elm, k, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: outputChildrenitems - } - ] - - node.on('contextmenu', d3.contextMenu(toolMenu)); - //############################################################################################################################## + + //aigner: Creation of input/output list + //############################################################ + function prepareIOList(theNode, io) + { + var links = d3.selectAll(".edgeBundlesLink")[0]; + var array={name_in:"",name_out:"",name:""}; + + links.forEach(function(d) + { + var theLink = d.__data__; + + + var pipeData_in = theLink.source.pipeline_data[theLink.target.name]; + var pipeData_out = theLink.target.pipeline_data[theLink.source.name]; + if (!pipeData_in){pipeData_in = [];} + if (!pipeData_out){pipeData_out = [];} + theLink.pipeData_in = theLink.source.pipeline_data[theLink.target.name]; + theLink.pipeData_out = theLink.target.pipeline_data[theLink.source.name]; + theLink.name_in = ""; + theLink.name_out = ""; + theLink.name = ""; + if (theLink.pipeData_in) + { + for (var i=0; i<theLink.pipeData_in.length; i++) + { + if (i==0){theLink.name_in += theLink.pipeData_in[i];} + else{theLink.name_in += "," + theLink.pipeData_in[i];} + + } + theLink.name += theLink.name_in + } + if (theLink.pipeData_out) + { + for (var i=0; i<theLink.pipeData_out.length; i++) + { + if (i==0){theLink.name_out += theLink.pipeData_out[i];} + else{theLink.name_out += "," + theLink.pipeData_out[i];} + } + theLink.name += theLink.name_out + } + + if (io=="in") + { + if (theLink.target == theNode) + { + if (array.name_in == ""){array.name_in +=theLink.name_out;} + else{array.name_in += "," + theLink.name_out;} + array.name_out = ""; + array.name = array.name_in; + } + if (theLink.source == theNode) + { + if (array.name_in == ""){array.name_in +=theLink.name_in;} + else{array.name_in += "," + theLink.name_in;} + array.name_out = ""; + array.name = array.name_in; + } + } + else if (io=="out") + { + if (theLink.source == theNode) + { + if (array.name_out == ""){array.name_out +=theLink.name_out;} + else{array.name_out += "," + theLink.name_out;} + array.name_in = ""; + array.name = array.name_out; + } + if (theLink.target == theNode) + { + if (array.name_out == ""){array.name_out +=theLink.name_in;} + else{array.name_out += "," + theLink.name_in;} + array.name_in = ""; + array.name = array.name_out; + } + } + }) + return array; + } + //############################################################ + + var inputChildrenitemsTree = []; + var outputChildrenitemsTree = []; + for (var j=0; j< varCategories.length; j++) + { + inputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"in")}, + onMouseOver: function(elm,data,i){}}); + outputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"out")}, + onMouseOver: function(elm,data,i){}}); + } + var inputChildrenitemsList = []; + var outputChildrenitemsList = []; + for (var j=0; j< varCategories.length; j++) + { + inputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var array = prepareIOList(elm.__data__,"in") + var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],array) + var title = "List view of all inputs for " + elm.__data__.id + "; Categorization: " + data.description; + showList(title,variables,nodeMenu) + }, + onMouseOver: function(elm,data,i){}}); + outputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var array = prepareIOList(elm.__data__,"out") + var variables = prepareTreeData(currentGraph.variableSchemes[data.varCategory],array) + var title = "List view of all outputs from " + elm.__data__.id + "; Categorization: " + data.description; + showList(title,variables,nodeMenu) + }, + onMouseOver: function(elm,data,i){}}); + } + //menu --> functions for right click options + var toolMenu = [ + { + title: 'Show competence info', + onMouseDown: function(elm, k, i) { + showToolTable(k); + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Show input variable tree...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: inputChildrenitemsTree + }, + { + title: 'Show output variable tree...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: outputChildrenitemsTree + }, + { + title: 'Show input variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: inputChildrenitemsList + }, + { + title: 'Show output variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: outputChildrenitemsList + } + ] + + node.on('contextmenu', d3.contextMenu(toolMenu)); + //############################################################################################################################## }; startEdgeBundles(data,graphID); @@ -22284,12 +23027,9 @@ } - - function createTreeLayout(theName, schema,aLink,theAllLinks) - { - //aigner: Build the tree layout - //###################################################################### - var theLink = aLink; + function prepareTreeData(aSchema,aLink) + { + var theLink = aLink; if (aLink.source && aLink.target) { var pipeData_in = theLink.source.pipeline_data[theLink.target.name]; @@ -22322,8 +23062,8 @@ } } - var treeData_in = (JSON.parse(JSON.stringify(schema))); - var treeData_out = (JSON.parse(JSON.stringify(schema))); + var treeData_in = (JSON.parse(JSON.stringify(aSchema))); + var treeData_out = (JSON.parse(JSON.stringify(aSchema))); //aigner: Here, the minimalized tree is created! //The tree will only be pruned if there is pipeData, such as in an edge or for the input of a tool if (theLink) @@ -22342,6 +23082,15 @@ //build tree layout for vistoms var treeData = treeData_in.concat(treeData_out) + + return treeData; + } + + function createTreeLayout(theName, schema,aLink,theAllLinks,nodeMenu) + { + //aigner: Build the tree layout + //###################################################################### + var treeData = prepareTreeData(schema, aLink) var newTree = {}; buildTree(newTree, treeData) treeData = newTree @@ -22598,492 +23347,174 @@ } else { - counter ++; - } - return counter; - } - - - var depths = []; - var labelLength = []; - nodes.forEach(function(d) - { - //aigner: If node is collapsed show number of ancestors - if (d._children) - { - d._childrenNum = countDescendants(d, 0); - d.text = d.name + " (" + d._childrenNum + ")"; - } - else - { - d.text = d.name - } - - //aigner: Find maximum labelLength for each level - if (!depths.includes(d.depth)) - { - depths.push(d.depth); - labelLength.push(d.text.length); - } - else - { - if (d.depth!=0){labelLength[depths.indexOf(d.depth)] = Math.max(d.text.length, labelLength[depths.indexOf(d.depth)]);} - } - }); - // Set widths between levels based on labelLength of each level. - var newWidth=0; - var depth_tmp = 0; - nodes.forEach(function(d) - { - if (d.parent) - { - d.y = d.parent.y+(labelLength[depths.indexOf(d.depth)])*10+50; - } - else{d.y=0} - - - if (newWidth<d.y) - {newWidth=d.y;} - - // console.log("##############") - // console.log(d.name) - // console.log("x = " + d.x) - // console.log("y = " + d.y) - // console.log("depth = " + depths.indexOf(d.depth)) - // console.log("##############") - }); - - - newWidth=Math.max(newWidth,getTextWidth(theName,"Arial 12pt")); - //aigner: Adjust height and width of the frame - $('.'+divClassName).lobiPanel('setWidth', newWidth + margin.top + margin.bottom +400+maxLabelLength*25+offset_tmp); - $('.'+divClassName).lobiPanel('setHeight', newHeight + margin.top + 2*margin.bottom+offset_tmp); - treeLayoutSVG = treeLayoutSVG.attr("height", newHeight + margin.top + margin.bottom+offset_tmp) - treeLayoutSVG = treeLayoutSVG.attr("width", newWidth + margin.top + margin.bottom +300+maxLabelLength*25+offset_tmp) - frame = frame.attr("height", newHeight + margin.top + margin.bottom) - frame = frame.attr("width", newWidth + margin.top + margin.bottom+300+maxLabelLength*15) - - - // Update the nodes… - var treeNode = svgGroup.selectAll("g.treeNode") - .data(nodes, function(d) { - return d.id || (d.id = ++i); - }); - - var dblclick_timer = false; - // Enter any new nodes at the parent's previous position. - var nodeEnter = treeNode.enter().append('g') - .attr('class', 'treeNode') - .attr("transform", function(d) { - return "translate(" + source.y0 + "," + source.x0 + ")"; - }) - .on("mousedown", function(d) { - if (d3.event.which != 3) - { - // if double click timer is active, this click is the double click - if ( dblclick_timer ) - { - clearTimeout(dblclick_timer) - dblclick_timer = false - // double click code code comes here - //console.log("DOUBLE CLICK") - dblclick(d); - } - // otherwise, what to do after single click (double click has timed out) - else dblclick_timer = setTimeout( function(){ - dblclick_timer = false - // single click code code comes here - //console.log("SINGLE CLICK") - click(d); - }, 250) - } - }) - - - nodeEnter.append("circle") - .attr('class', 'nodeCircle') - .attr("r", 0) - .style("fill", function(d) { - if (d._children) - { - if(d.pipeLineIn && !d.pipeLineOut){return '#ea9999'} - else if(!d.pipeLineIn && d.pipeLineOut){return '#d6ea99'} - else {return "lightsteelblue"} - } - else{return "#fff";} - }) - .style("stroke", function(d) { - if(d.pipeLineIn && !d.pipeLineOut){ - //console.log(d); - return '#CC0000'} - else if(!d.pipeLineIn && d.pipeLineOut){ - //console.log(d); - return '#99CC00'} - }) - .attr("cx", function(d) {return xOffset}); - - nodeEnter.append("text") - .attr("x", function(d) - { - return d.children || d._children ? -10+xOffset : 10+xOffset; - }) - .attr("dy", ".35em") - .attr('class', 'nodeText') - .attr("text-anchor", function(d) { - return d.children || d._children ? "end" : "start"; - }) - .text(function(d) { - return d.text; - }) - .style("fill-opacity", 0) - - - // Update the text to reflect whether node has children or not. - treeNode.select('text') - .attr("x", function(d) { - return d.children || d._children ? -10+xOffset : 10+xOffset; - }) - .attr("text-anchor", function(d) { - return d.children || d._children ? "end" : "start"; - }) - .text(function(d) { - return d.text; - }); - - // Change the circle fill depending on whether it has children and is collapsed - treeNode.select("circle.nodeCircle") - .attr("r", 4.5) - .style("fill", function(d) { - if (d._children) - { - if(d.pipeLineIn && !d.pipeLineOut){return '#ea9999'} - else if(!d.pipeLineIn && d.pipeLineOut){return '#d6ea99'} - else {return "lightsteelblue"} - } - else{return "#fff";} - }) - - - function showVariableTable(aVariable) - { - - var headLine = "Node Information (" + aVariable.name + ")"; - var data = []; - // render the table(s) - data.push({ "name" : "Name", "value" : "\""+aVariable.name+"\"" }) - data.push({ "name" : "xPath", "value" : aVariable.xPath }) - if (aVariable.type){data.push({ "name" : "Type", "value" : aVariable.type })} - if (aVariable.level){data.push({ "name" : "Level", "value" : aVariable.level })} - if (aVariable.children || aVariable._children) - { - var childrenNum=0; - if (aVariable.children){childrenNum=childrenNum+aVariable.children.length} - if (aVariable._children){childrenNum=childrenNum+aVariable._children.length} - data.push({ "name" : "Number of children", "value" : childrenNum }) - } - if (aVariable.dimension){data.push({ "name" : "Dimension", "value" : aVariable.dimension })} - else if(aVariable.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} - if (aVariable.value){data.push({ "name" : "Value(s)", "value" : aVariable.value })} - - var d3_body = d3.select("body"); - - var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") - panel_div.append("div").attr("class","panel-heading") - .append("div").attr("class","panel_title").append("h4").text(headLine) - var listGroup = panel_div.append("div").attr("class","panel-body") - .append("table").attr("id","myTable") - .append("tbody") - - data.forEach(function(listElement) - { - var row = listGroup.append("tr") - row.append("td").text(listElement.name) - row.append("td").text(listElement.value) - - }) - $('.myPanel').lobiPanel({ - reload: false, - editTitle: false, - expand: false, - unpin: false, - resize: "none", - minWidth: 200, - minHeight: 200, - maxWidth: 1100, - maxHeight: 1100, - }); - $('.myPanel').lobiPanel('unpin'); - } - - //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) - { - aText = "/"+data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - allLinks[0].forEach(function(aLink) - { - - aLink.__data__.pipeData_in = aLink.__data__.source.pipeline_data[aLink.__data__.target.name]; - aLink.__data__.pipeData_out = aLink.__data__.target.pipeline_data[aLink.__data__.source.name]; - aLink.__data__.pipeDataName_in = ""; - aLink.__data__.pipeDataName_out = ""; - aLink.__data__.name = ""; - if (aLink.__data__.pipeData_in) - { - for (var i=0; i<aLink.__data__.pipeData_in.length; i++) - { - if (i==0){aLink.__data__.pipeDataName_in += aLink.__data__.pipeData_in[i];} - else{aLink.__data__.pipeDataName_in += "," + aLink.__data__.pipeData_in[i];} - - } - aLink.__data__.name += aLink.__data__.pipeDataName_in - } - if (aLink.__data__.pipeData_out) - { - for (var i=0; i<aLink.__data__.pipeData_out.length; i++) - { - if (i==0){aLink.__data__.pipeDataName_out += aLink.__data__.pipeData_out[i];} - else{aLink.__data__.pipeDataName_out += "," + aLink.__data__.pipeData_out[i];} - } - aLink.__data__.name += aLink.__data__.pipeDataName_out - } - }) - - //var allLinks_tmp = allLinks[0]; - allLinks[0].forEach(function(p) { - var firstElement_tmp = p.__data__.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.__data__.name,text_fromFirst)) - { - d3.select(p) - .style("stroke-opacity", 1.0) - } - else - { - d3.select(p).style("stroke-opacity", 0); - } - }); - } - } - - //Function writeTreeToXML goes through tree nodes and puts the into an xml document - function writeTreeToXML(aNode,anXMLDoc,anXPath) - { - //Variable "children" - //--> One children variable, no matter whether a node has "_children" (collapsed) or "children" (expanded) - var children; - if (aNode._children){children = aNode._children;} - else if (aNode.children){children = aNode.children;} - - //Get current xml element with its xPath - var element = anXMLDoc.evaluate(anXPath,anXMLDoc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; - if (element != null) {element.value = '...';} - - //If a node has children (collapsed or expanded), loop through them - if (children) - { - for (var i=0; i < children.length;i++) - { - //Name of the new XML element --> childName - var child = children[i]; - var childName = child.name.split(/[\[\]]+/);//Split childName at "[]" which is the uID - var cleanChildName = childName[0].split(/[\+\*\^\-\ \#]+/);//Split childName all special characters - var newNode = anXMLDoc.createElement(String(cleanChildName[0])); - - //The children are appended to the xPath --> newXPath - var newXPath = anXPath+"/"+cleanChildName[0]; - - //If childName contains a uID, make the uID an attribute - if (childName[1]) - { - if (parseInt(childName[1])) - { - var dummyID = childName[1]; - newNode.setAttribute("dummyID", dummyID) - newXPath = newXPath+"[@dummyID='"+dummyID+"']"; - } - else - { - var uID = childName[1]; - newNode.setAttribute("uID", uID) - newXPath = newXPath+"[@uID='"+uID+"']"; - } - } - if (cleanChildName.length>1) {newNode.setAttribute("elementName", childName[0])}; - - //Append the newNode to the xml structure - element.appendChild(newNode); - - - - ////aigner: Sorting of XML elements according to "uID" - // var items = element.children; - // var itemsArr = []; - // for (var j in items) { - // if (items[j].nodeType == 1) { // get rid of the whitespace text nodes - // itemsArr.push(items[j]); - // } - // } - // itemsArr.sort(function(a,b){ - // if (a.getAttribute("uID") < b.getAttribute("uID")) - // return -1; - // if (a.getAttribute("uID") > b.getAttribute("uID")) - // return 1; - // return 0; - // }); - - // for (j = 0; j < itemsArr.length; ++j) { - // element.appendChild(itemsArr[j]); - // } - - //call function writeTreeToXML recursively for all children - writeTreeToXML(child,anXMLDoc,newXPath) - } - } - else - { - if (aNode.value){element.innerHTML = String(aNode.value);} - else{element.innerHTML = " ";} - } - //return the xml document - return anXMLDoc; - } - - function removeAttributeInAllElements(aDocument,attribute) - { - var matchingElements = []; - var allElements = aDocument.getElementsByTagName('*'); - for (var i = 0, n = allElements.length; i < n; i++) - { - if (allElements[i].getAttribute(attribute) !== null) - { - allElements[i].removeAttribute(attribute); - } - } - return matchingElements; - } - - function putAncestorsInXMLString(strWrapper, aNode) - { - //Name of the new XML element - var nodeName = aNode.name.split(/[\[\]]+/);//Split name at "[]" which is the uID - var cleanNodeName = nodeName[0].split(/[\+\*\^\-\ \#]+/);//Split nodeName all special characters - //If nodeName contains a uID, make the uID an attribute - if (nodeName[1]) - { - var uID = nodeName[1]; - strWrapper.val = "<"+cleanNodeName[0]+" uID='"+ uID +"'>"+strWrapper.val+"</"+cleanNodeName[0]+">";; - } - else - { - strWrapper.val = "<"+cleanNodeName[0]+">"+strWrapper.val+"</"+cleanNodeName[0]+">";; - } - var aParent = aNode.parent; - if (aParent) - { - return putAncestorsInXMLString(strWrapper, aParent); - } - else - { - return strWrapper; + counter ++; } + return counter; } - function putAncestorsInXPath(strWrapper, aNode) - { - //Name of the new XML element - var nodeName = aNode.name.split(/[\[\]]+/);//Split name at "[]" which is the uID - var cleanNodeName = nodeName[0].split(/[\+\*\^\-\ \#]+/);//Split nodeName all special characters - //If nodeName contains a uID, make the uID an attribute - if (nodeName[1]) + + var depths = []; + var labelLength = []; + nodes.forEach(function(d) + { + //aigner: If node is collapsed show number of ancestors + if (d._children) { - var uID = nodeName[1]; - strWrapper.val = "/"+cleanNodeName[0]+"[@uID='"+uID+"']"+strWrapper.val; + d._childrenNum = countDescendants(d, 0); + d.text = d.name + " (" + d._childrenNum + ")"; } - else + else { - strWrapper.val = "/"+cleanNodeName[0]+strWrapper.val; + d.text = d.name } - var aParent = aNode.parent; - if (aParent) + + //aigner: Find maximum labelLength for each level + if (!depths.includes(d.depth)) { - return putAncestorsInXPath(strWrapper, aParent); + depths.push(d.depth); + labelLength.push(d.text.length); } - else + else { - return strWrapper; + if (d.depth!=0){labelLength[depths.indexOf(d.depth)] = Math.max(d.text.length, labelLength[depths.indexOf(d.depth)]);} } - } + }); + // Set widths between levels based on labelLength of each level. + var newWidth=0; + var depth_tmp = 0; + nodes.forEach(function(d) + { + if (d.parent) + { + d.y = d.parent.y+(labelLength[depths.indexOf(d.depth)])*10+50; + } + else{d.y=0} + + + if (newWidth<d.y) + {newWidth=d.y;} + + // console.log("##############") + // console.log(d.name) + // console.log("x = " + d.x) + // console.log("y = " + d.y) + // console.log("depth = " + depths.indexOf(d.depth)) + // console.log("##############") + }); - // Function to download data to a file - function download(filename, text) { - var element = document.createElement('a'); - element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); - element.setAttribute('download', filename); + + newWidth=Math.max(newWidth,getTextWidth(theName,"Arial 12pt")); + //aigner: Adjust height and width of the frame + $('.'+divClassName).lobiPanel('setWidth', newWidth + margin.top + margin.bottom +400+maxLabelLength*25+offset_tmp); + $('.'+divClassName).lobiPanel('setHeight', newHeight + margin.top + 2*margin.bottom+offset_tmp); + treeLayoutSVG = treeLayoutSVG.attr("height", newHeight + margin.top + margin.bottom+offset_tmp) + treeLayoutSVG = treeLayoutSVG.attr("width", newWidth + margin.top + margin.bottom +300+maxLabelLength*25+offset_tmp) + frame = frame.attr("height", newHeight + margin.top + margin.bottom) + frame = frame.attr("width", newWidth + margin.top + margin.bottom+300+maxLabelLength*15) - element.style.display = 'none'; - document.body.appendChild(element); - element.click(); + // Update the nodes… + var treeNode = svgGroup.selectAll("g.treeNode") + .data(nodes, function(d) { + return d.id || (d.id = ++i); + }); - document.body.removeChild(element); - } + var dblclick_timer = false; + // Enter any new nodes at the parent's previous position. + var nodeEnter = treeNode.enter().append('g') + .attr('class', 'treeNode') + .attr("transform", function(d) { + return "translate(" + source.y0 + "," + source.x0 + ")"; + }) + .on("mousedown", function(d) { + if (d3.event.which != 3) + { + // if double click timer is active, this click is the double click + if ( dblclick_timer ) + { + clearTimeout(dblclick_timer) + dblclick_timer = false + // double click code code comes here + //console.log("DOUBLE CLICK") + dblclick(d); + } + // otherwise, what to do after single click (double click has timed out) + else dblclick_timer = setTimeout( function(){ + dblclick_timer = false + // single click code code comes here + //console.log("SINGLE CLICK") + click(d); + }, 250) + } + }) + - //menu --> functions for right click options - var nodeMenu = [ - { - title: 'Show node information', - onMouseDown: function(elm, d, i) { - showVariableTable(d); - }, - onMouseUp: function(elm, d, i) {}, - onMouseOver: function(elm, d, i) {}, - childrenItems: [] - }, - { - title: 'Show usage of node in diagram', - onMouseDown: function(elm, d, i) { - d3.selectAll(".treeFrame").attr("fill-opacity", .5); - d3.selectAll(".nodeText").style("fill-opacity", 0.5); - var theText=""; - highlight(d,theText); - }, - onMouseUp: function(elm, d, i) { - d3.selectAll(".edgeBundlesLink") - .style("stroke-opacity",.4) - d3.selectAll(".treeFrame").attr("fill-opacity", .8); - d3.selectAll(".nodeText").style("fill-opacity", 1); - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Copy x-path to clipboard', - onMouseDown: function(elm, d, i) { - function copyToClipboard(text) + nodeEnter.append("circle") + .attr('class', 'nodeCircle') + .attr("r", 0) + .style("fill", function(d) { + if (d._children) { - window.prompt("Copy to clipboard: Ctrl+C, Enter", text); + if(d.pipeLineIn && !d.pipeLineOut){return '#ea9999'} + else if(!d.pipeLineIn && d.pipeLineOut){return '#d6ea99'} + else {return "lightsteelblue"} } - function copyXPathToClipboard(data,aText) + else{return "#fff";} + }) + .style("stroke", function(d) { + if(d.pipeLineIn && !d.pipeLineOut){ + //console.log(d); + return '#CC0000'} + else if(!d.pipeLineIn && d.pipeLineOut){ + //console.log(d); + return '#99CC00'} + }) + .attr("cx", function(d) {return xOffset}); + + nodeEnter.append("text") + .attr("x", function(d) + { + return d.children || d._children ? -10+xOffset : 10+xOffset; + }) + .attr("dy", ".35em") + .attr('class', 'nodeText') + .attr("text-anchor", function(d) { + return d.children || d._children ? "end" : "start"; + }) + .text(function(d) { + return d.text; + }) + .style("fill-opacity", 0) + + + // Update the text to reflect whether node has children or not. + treeNode.select('text') + .attr("x", function(d) { + return d.children || d._children ? -10+xOffset : 10+xOffset; + }) + .attr("text-anchor", function(d) { + return d.children || d._children ? "end" : "start"; + }) + .text(function(d) { + return d.text; + }); + + // Change the circle fill depending on whether it has children and is collapsed + treeNode.select("circle.nodeCircle") + .attr("r", 4.5) + .style("fill", function(d) { + if (d._children) { - aText = "/"+data.name+aText; - if (data.parent){copyXPathToClipboard(data.parent,aText)} - else{copyToClipboard(aText);} + if(d.pipeLineIn && !d.pipeLineOut){return '#ea9999'} + else if(!d.pipeLineIn && d.pipeLineOut){return '#d6ea99'} + else {return "lightsteelblue"} } - var copyText=""; - copyXPathToClipboard(d,copyText); - d3.select('.d3-context-menu').style('display', 'none'); - }, - onMouseUp: function(elm, d, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { + else{return "#fff";} + }) + + var nodeTreeMenu = nodeMenu; + var treeMenu = [ + { title: 'Download full tree as XML-file', onMouseDown: function(elm, d, i) { //Begin xml structure with the first element @@ -23135,10 +23566,11 @@ childrenItems: [] } ] + var nodeTreeMenu = nodeMenu.concat(treeMenu) nodeEnter.append("svg:title").text("Click left to expand, click right to inspect") - nodeEnter = nodeEnter.on('contextmenu', d3.contextMenu(nodeMenu)); + nodeEnter = nodeEnter.on('contextmenu', d3.contextMenu(nodeTreeMenu)); // UPDATE // Transition nodes to their new position. @@ -24414,12 +24846,172 @@ } }); + + //Highlight function, that shows usage of a node in the XDSM + function highlight(data,aText) + { + aText = "/"+data.name+aText; + if (data.parent){highlight(data.parent,aText)} + else + { + var allLinks = d3.selectAll(".link"); + var allLinks_tmp = allLinks[0]; + allLinks_tmp.forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p).style("opacity", .8); + } + else + { + d3.select(p).style("opacity", 0); + } + }); + } + } + + function showVariableTable(aVariable) + { + var headLine = "Node Information (" + aVariable.name + ")"; + var data = []; + // render the table(s) + data.push({ "name" : "Name", "value" : "\""+aVariable.name+"\"" }) + data.push({ "name" : "xPath", "value" : aVariable.xPath }) + if (aVariable.type){data.push({ "name" : "Type", "value" : aVariable.type })} + if (aVariable.level){data.push({ "name" : "Level", "value" : aVariable.level })} + if (aVariable.children || aVariable._children) + { + var childrenNum=0; + if (aVariable.children){childrenNum=childrenNum+aVariable.children.length} + if (aVariable._children){childrenNum=childrenNum+aVariable._children.length} + data.push({ "name" : "Number of children", "value" : childrenNum }) + } + if (aVariable.dimension){data.push({ "name" : "Dimension", "value" : aVariable.dimension })} + else if(aVariable.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} + if (aVariable.value){data.push({ "name" : "Value(s)", "value" : aVariable.value })} + + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(headLine) + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + data.forEach(function(listElement) + { + var row = listGroup.append("tr") + row.append("td").text(listElement.name) + row.append("td").text(listElement.value) + + }) + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + } + + //menu --> functions for right click options + var nodeMenu = [ + { + title: 'Show node information', + onMouseDown: function(elm, d, i) { + showVariableTable(d); + }, + onMouseUp: function(elm, d, i) {}, + onMouseOver: function(elm, d, i) {}, + childrenItems: [] + }, + { + title: 'Show usage of node in diagram', + onMouseDown: function(elm, d, i) { + d3.selectAll(".treeFrame").attr("fill-opacity", .5); + d3.selectAll(".nodeText").style("fill-opacity", 0.5); + var theText=""; + highlight(d,theText); + }, + onMouseUp: function(elm, d, i) { + d3.selectAll(".link").style("opacity",.6) + d3.selectAll(".treeFrame").attr("fill-opacity", .8); + d3.selectAll(".nodeText").style("fill-opacity", 1); + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Copy x-path to clipboard', + onMouseDown: function(elm, d, i) { + window.prompt("Copy to clipboard: Ctrl+C, Enter", d.xPath); + d3.select('.d3-context-menu').style('display', 'none'); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + } + ] + + function showList(aTitle,aList,aMenu) + { + if (aList.length != 0) + { + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(aTitle) + panel_div.append("input") + .attr("id","myInput") + .attr("placeholder","Filter search...") + .attr("title","Type in a name") + .attr("onkeyup","filterSearch()") + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + var tr = listGroup + .selectAll('tr') + .data(aList).enter() + .append('tr') + var td = tr.append("td").html(function(d) { + if (d.xPath){return d.xPath;} + else {return d.name;} + }) + tr.on('contextmenu', d3.contextMenu(aMenu)); + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + $('.myPanel').lobiPanel('height','5000'); + } + } + function showLinkTree(aLink,aVarCategory) { var name_tmp = "Variable flow: " + aLink.__data__.source.name + " → " + aLink.__data__.target.name var theSchema = currentGraph.variableSchemes[aVarCategory]; - createTreeLayout(name_tmp,theSchema,aLink.__data__.name,link); + createTreeLayout(name_tmp,theSchema,aLink.__data__.name,link,nodeMenu); } function showEdgeTable(aLink) @@ -24488,20 +25080,43 @@ minWidth: 200, minHeight: 200, maxWidth: 1100, - maxHeight: 1100, + maxHeight: 1200, }); $('.myPanel').lobiPanel('unpin'); } //linkMenu --> functions for right click options - var linkChildrenItems = []; + var linkChildrenItemsTree = []; for (var j=0; j< varCategories.length; j++) { - linkChildrenItems.push({title: 'according to ' + varCategories[j].description, + linkChildrenItemsTree.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, onMouseClick: function(elm, data, i) {showLinkTree(elm,data.varCategory)}, onMouseOver: function(elm,data,i){}}); } + var linkChildrenItemsList = []; + for (var j=0; j< varCategories.length; j++) + { + linkChildrenItemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + onMouseClick: function(elm, data, i) { + var variables = []; + var pipeData = elm.__data__.name; + var title = "List view of variable flow: " + elm.__data__.source.id + " → " + elm.__data__.target.id + variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) + prune_tree(pipeData,variables) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + }, + onMouseOver: function(elm,data,i){}}); + } var linkMenu = [ { title: 'Show edge info', @@ -24522,7 +25137,17 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: linkChildrenItems + childrenItems: linkChildrenItemsTree + }, + { + title: 'Show variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: linkChildrenItemsList } ] @@ -24708,7 +25333,7 @@ minWidth: 200, minHeight: 200, maxWidth: 1100, - maxHeight: 1100, + maxHeight: 1200, }); $('.myPanel').lobiPanel('unpin'); } @@ -24740,29 +25365,90 @@ name_tmp = "Output tree view:" + theNode.id + "; Categorization: " + categoryDescr; } }) - - var theSchema = currentGraph.variableSchemes[categoryID]; - createTreeLayout(name_tmp,theSchema,array,link) + var theSchema = JSON.parse(JSON.stringify(currentGraph.variableSchemes[categoryID])); + createTreeLayout(name_tmp,theSchema,array,link,nodeMenu) } //############################################################ - var inputChildrenitems = []; - var outputChildrenitems = []; - var inputChildrenitems = []; - var outputChildrenitems = []; + var inputChildrenitemsTree = []; + var outputChildrenitemsTree = []; for (var j=0; j< varCategories.length; j++) { - inputChildrenitems.push({title: 'according to ' + varCategories[j].description, + inputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"in")}, onMouseOver: function(elm,data,i){}}); - outputChildrenitems.push({title: 'according to ' + varCategories[j].description, + outputChildrenitemsTree.push({title: 'according to ' + varCategories[j].description, varCategory: varCategories[j].name, description: varCategories[j].description, onMouseClick: function(elm, data, i) {showIOTree(data.varCategory,data.description,elm.__data__,"out")}, onMouseOver: function(elm,data,i){}}); } + var inputChildrenitemsList = []; + var outputChildrenitemsList = []; + for (var j=0; j< varCategories.length; j++) + { + inputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var links = d3.selectAll(".link"); + var pipeData=""; + var name_tmp = ""; + links.each(function(theLink) + { + if (theLink.to == elm.__data__.id) + { + pipeData = pipeData + "," + theLink.name; + } + }) + + var title = "List view of all inputs for " + elm.__data__.id + "; Categorization: " + data.description + var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) + prune_tree(pipeData,variables) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + }, + onMouseOver: function(elm,data,i){}}); + outputChildrenitemsList.push({title: 'according to ' + varCategories[j].description, + varCategory: varCategories[j].name, + description: varCategories[j].description, + onMouseClick: function(elm, data, i) { + var links = d3.selectAll(".link"); + var pipeData=""; + var name_tmp = ""; + links.each(function(theLink) + { + if (theLink.from == elm.__data__.id) + { + pipeData = pipeData + "," + theLink.name; + } + }) + + var title = "List view of all outputs from " + elm.__data_.id + "; Categorization: " + data.description + var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[data.varCategory])) + prune_tree(pipeData,variables) + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + + showList(title,variables,nodeMenu); + + }, + onMouseOver: function(elm,data,i){}}); + } //menu --> functions for right click options var toolMenu = [ { @@ -24784,7 +25470,7 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: inputChildrenitems + childrenItems: inputChildrenitemsTree }, { title: 'Show output variable tree...', @@ -24794,7 +25480,27 @@ }, onMouseOver: function(elm, d, i) { }, - childrenItems: outputChildrenitems + childrenItems: outputChildrenitemsTree + }, + { + title: 'Show input variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: inputChildrenitemsList + }, + { + title: 'Show output variable list...', + onMouseDown: function(elm, k, i) { + }, + onMouseUp: function(elm, k, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: outputChildrenitemsList } ] //############################################################################################################################## @@ -24899,7 +25605,7 @@ } - function createTreeLayout(theName,schema,theLinks,theAllLinks) + function createTreeLayout(theName,schema,theLinks,theAllLinks,nodeMenu) { //aigner: Build the tree layout //###################################################################### @@ -24962,7 +25668,7 @@ } } } - + // Call visit function to establish maxLabelLength visit(treeData, function(d) { totalNodes++; @@ -25224,79 +25930,6 @@ frame = frame.attr("height", newHeight + margin.top + margin.bottom) frame = frame.attr("width", newWidth + margin.top + margin.bottom+300+maxLabelLength*15) - - function showVariableTable(aVariable) - { - var headLine = "Node Information (" + aVariable.name + ")"; - var data = []; - // render the table(s) - data.push({ "name" : "Name", "value" : "\""+aVariable.name+"\"" }) - data.push({ "name" : "xPath", "value" : aVariable.xPath }) - if (aVariable.type){data.push({ "name" : "Type", "value" : aVariable.type })} - if (aVariable.level){data.push({ "name" : "Level", "value" : aVariable.level })} - if (aVariable.children || aVariable._children) - { - var childrenNum=0; - if (aVariable.children){childrenNum=childrenNum+aVariable.children.length} - if (aVariable._children){childrenNum=childrenNum+aVariable._children.length} - data.push({ "name" : "Number of children", "value" : childrenNum }) - } - if (aVariable.dimension){data.push({ "name" : "Dimension", "value" : aVariable.dimension })} - else if(aVariable.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} - if (aVariable.value){data.push({ "name" : "Value(s)", "value" : aVariable.value })} - - var d3_body = d3.select("body"); - - var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") - panel_div.append("div").attr("class","panel-heading") - .append("div").attr("class","panel_title").append("h4").text(headLine) - var listGroup = panel_div.append("div").attr("class","panel-body") - .append("table").attr("id","myTable") - .append("tbody") - - data.forEach(function(listElement) - { - var row = listGroup.append("tr") - row.append("td").text(listElement.name) - row.append("td").text(listElement.value) - - }) - $('.myPanel').lobiPanel({ - reload: false, - editTitle: false, - expand: false, - unpin: false, - resize: "none", - minWidth: 200, - minHeight: 200, - maxWidth: 1100, - maxHeight: 1100, - }); - $('.myPanel').lobiPanel('unpin'); - } - - //Highlight function, that shows usage of a node in the XDSM - function highlight(data,aText) - { - aText = "/"+data.name+aText; - if (data.parent){highlight(data.parent,aText)} - else - { - var allLinks_tmp = allLinks[0]; - allLinks_tmp.forEach(function(p) { - var firstElement_tmp = p.__data__.name.split("/")[1] - var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] - if (include(p.__data__.name,text_fromFirst)) - { - d3.select(p).style("opacity", .8); - } - else - { - d3.select(p).style("opacity", 0); - } - }); - } - } //Function writeTreeToXML goes through tree nodes and puts the into an xml document function writeTreeToXML(aNode,anXMLDoc,anXPath) @@ -25461,58 +26094,10 @@ document.body.removeChild(element); } - //menu --> functions for right click options - var nodeMenu = [ - { - title: 'Show node information', - onMouseDown: function(elm, d, i) { - showVariableTable(d); - }, - onMouseUp: function(elm, d, i) {}, - onMouseOver: function(elm, d, i) {}, - childrenItems: [] - }, - { - title: 'Show usage of node in diagram', - onMouseDown: function(elm, d, i) { - d3.selectAll(".treeFrame").attr("fill-opacity", .5); - d3.selectAll(".nodeText").style("fill-opacity", 0.5); - var theText=""; - highlight(d,theText); - }, - onMouseUp: function(elm, d, i) { - d3.selectAll(".link").style("opacity",.6) - d3.selectAll(".treeFrame").attr("fill-opacity", .8); - d3.selectAll(".nodeText").style("fill-opacity", 1); - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { - title: 'Copy x-path to clipboard', - onMouseDown: function(elm, d, i) { - function copyToClipboard(text) - { - window.prompt("Copy to clipboard: Ctrl+C, Enter", text); - } - function copyXPathToClipboard(data,aText) - { - aText = "/"+data.name+aText; - if (data.parent){copyXPathToClipboard(data.parent,aText)} - else{copyToClipboard(aText);} - } - var copyText=""; - copyXPathToClipboard(d,copyText); - d3.select('.d3-context-menu').style('display', 'none'); - }, - onMouseUp: function(elm, d, i) { - }, - onMouseOver: function(elm, d, i) { - }, - childrenItems: [] - }, - { + + var treeNodeMenu = nodeMenu; + var treeMenu = [ + { title: 'Download full tree as XML-file', onMouseDown: function(elm, d, i) { //Begin xml structure with the first element @@ -25563,10 +26148,8 @@ }, childrenItems: [] } - ] - - - + ] + treeNodeMenu = nodeMenu.concat(treeMenu) // Update the nodes… @@ -25582,7 +26165,7 @@ .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) - .on('contextmenu', d3.contextMenu(nodeMenu)) + .on('contextmenu', d3.contextMenu(treeNodeMenu)) .on("mousedown", function(d) { if (d3.event.which != 3) { @@ -25743,7 +26326,8 @@ } - //aigner: Here the data is read and the sankey diagram is created + + //aigner: Here the data is read and the sankey diagram is created //#####################################################################// var graphs, currentGraph, varCategories, entireData; function startSankeyDiagram(data, graphID) @@ -25759,6 +26343,121 @@ } varCategories = entireData.categories; + //Highlight function, that shows usage of a node in the XDSM + function highlight(data,aText) + { + aText = "/"+data.name+aText; + if (data.parent){highlight(data.parent,aText)} + else + { + var allLinks = d3.selectAll(".link"); + var allLinks_tmp = allLinks[0]; + allLinks_tmp.forEach(function(p) { + var firstElement_tmp = p.__data__.name.split("/")[1] + var text_fromFirst = "/"+firstElement_tmp+aText.split(firstElement_tmp)[1] + if (include(p.__data__.name,text_fromFirst)) + { + d3.select(p).style("opacity", .8); + } + else + { + d3.select(p).style("opacity", 0); + } + }); + } + } + + function showVariableTable(aVariable) + { + var headLine = "Node Information (" + aVariable.name + ")"; + var data = []; + // render the table(s) + data.push({ "name" : "Name", "value" : "\""+aVariable.name+"\"" }) + data.push({ "name" : "xPath", "value" : aVariable.xPath }) + if (aVariable.type){data.push({ "name" : "Type", "value" : aVariable.type })} + if (aVariable.level){data.push({ "name" : "Level", "value" : aVariable.level })} + if (aVariable.children || aVariable._children) + { + var childrenNum=0; + if (aVariable.children){childrenNum=childrenNum+aVariable.children.length} + if (aVariable._children){childrenNum=childrenNum+aVariable._children.length} + data.push({ "name" : "Number of children", "value" : childrenNum }) + } + if (aVariable.dimension){data.push({ "name" : "Dimension", "value" : aVariable.dimension })} + else if(aVariable.dimension===null){data.push({ "name" : "Dimension", "value" : "undefined" })} + if (aVariable.value){data.push({ "name" : "Value(s)", "value" : aVariable.value })} + + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(headLine) + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + data.forEach(function(listElement) + { + var row = listGroup.append("tr") + row.append("td").text(listElement.name) + row.append("td").text(listElement.value) + + }) + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + } + + //menu --> functions for right click options + var nodeMenu = [ + { + title: 'Show node information', + onMouseDown: function(elm, d, i) { + showVariableTable(d); + }, + onMouseUp: function(elm, d, i) {}, + onMouseOver: function(elm, d, i) {}, + childrenItems: [] + }, + { + title: 'Show usage of node in diagram', + onMouseDown: function(elm, d, i) { + d3.selectAll(".treeFrame").attr("fill-opacity", .5); + d3.selectAll(".nodeText").style("fill-opacity", 0.5); + var theText=""; + highlight(d,theText); + }, + onMouseUp: function(elm, d, i) { + d3.selectAll(".link").style("opacity",.6) + d3.selectAll(".treeFrame").attr("fill-opacity", .8); + d3.selectAll(".nodeText").style("fill-opacity", 1); + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + }, + { + title: 'Copy x-path to clipboard', + onMouseDown: function(elm, d, i) { + window.prompt("Copy to clipboard: Ctrl+C, Enter", d.xPath); + d3.select('.d3-context-menu').style('display', 'none'); + }, + onMouseUp: function(elm, d, i) { + }, + onMouseOver: function(elm, d, i) { + }, + childrenItems: [] + } + ] var graph = currentGraph.xdsm; var theNodes = graph.nodes @@ -25768,6 +26467,7 @@ link.target = link.to; link.value = link.name.split(",").length }); + //################################################################################################// var headerDiv = sankeyDiagramDiv.append("div").attr("class","panel panel-primary") @@ -25798,7 +26498,7 @@ var emptyArray=""; var allLinks = d3.selectAll(".link"); var theSchema = currentGraph.variableSchemes[categoryID]; - createTreeLayout(name_tmp,theSchema,emptyArray,allLinks); + createTreeLayout(name_tmp,theSchema,emptyArray,allLinks,nodeMenu); } var childrenItems = []; @@ -25822,13 +26522,53 @@ childrenItems: childrenItems } ] - //#####################################################################// - + //#####################################################################// + + function showList(aTitle,aList,aMenu) + { + if (aList.length != 0) + { + var d3_body = d3.select("body"); + + var panel_div = d3_body.append("div").attr("class", "myPanel panel-default") + panel_div.append("div").attr("class","panel-heading") + .append("div").attr("class","panel_title").append("h4").text(aTitle) + panel_div.append("input") + .attr("id","myInput") + .attr("placeholder","Filter search...") + .attr("title","Type in a name") + .attr("onkeyup","filterSearch()") + var listGroup = panel_div.append("div").attr("class","panel-body") + .append("table").attr("id","myTable") + .append("tbody") + + var tr = listGroup + .selectAll('tr') + .data(aList).enter() + .append('tr') + var td = tr.append("td").html(function(d) { + if (d.xPath){return d.xPath;} + else {return d.name;} + }) + tr.on('contextmenu', d3.contextMenu(aMenu)); + $('.myPanel').lobiPanel({ + reload: false, + editTitle: false, + expand: false, + unpin: false, + resize: "none", + minWidth: 200, + minHeight: 200, + maxWidth: 1100, + maxHeight: 1200, + }); + $('.myPanel').lobiPanel('unpin'); + $('.myPanel').lobiPanel('height','5000'); + } + } - //aigner: treeLayout in the bottom - //################################################################################################// - //aigner: Data Model Expand Button - //########################################################## + //aigner: Data Model Tree View Button + //#################################################################################################################### var dataModelDiv = d3.select(".sankeyDiagramDiv").append("div").attr("class","dataModelDiv").attr("transform","translate(10,0)") var ul = dataModelDiv.append("ul") var dropdown1 = ul.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) @@ -25840,8 +26580,10 @@ .style("margin-bottom","0px") .attr("height","20") .attr("width","20") - dropdown1.append("a").text("Data Model") + dropdown1.append("a").text("Data Model Tree") var links = dropdown1.append("ul"); + var xOffset_ul = dropdown1[0][0].offsetLeft+dropdown1[0][0].offsetWidth-40; + links.style("left", String(xOffset_ul)+"px") for (var j=0; j< varCategories.length; j++) { //console.log(varCategories[j]) @@ -25856,12 +26598,53 @@ }) } //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works - dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") - //########################################################## - //################################################################################################// + //dataModelDiv.style("width", String(dropdown1.node().getBoundingClientRect().width+20)+"px") + //#################################################################################################################### + + //aigner: Data Model List View Button + //#################################################################################################################### + var ul_list = dataModelDiv.append("ul") + var dropdownList = ul_list.append("li").on("mouseover", function(){d3.select(this).style("cursor", "default")}) + dropdownList.append("img").attr("src",fileReference.AGILE_Icon) + .attr("align","left") + .style("margin-left","6px") + .style("margin-right","-10px") + .style("margin-top","10px") + .style("margin-bottom","0px") + .attr("height","20") + .attr("width","20") + dropdownList.append("a").text("Data Model List") + var linksList = dropdownList.append("ul"); + var xOffset_ul = dropdownList[0][0].offsetLeft+dropdownList[0][0].offsetWidth-40; + linksList.style("left", String(xOffset_ul)+"px") + for (var j=0; j< varCategories.length; j++) + { + //console.log(varCategories[j]) + var linkLi = linksList.append("li"); + var linkA = linkLi.append("a") + .attr("id",j) + .text(varCategories[j].description) + .on("mouseover", function(){d3.select(this).style("cursor", "pointer")}) + .on("click", function() + { + var variables = JSON.parse(JSON.stringify(currentGraph.variableSchemes[varCategories[this.id].name])); + variables.forEach(function(variable) + { + variable.name = variable.xPath + //work around because nodeMenu expexts the data, to have a "data" object inside + variable.data = variable + variable.data.name = variable.xPath.split("/")[variable.xPath.split("/").length-1] + }) + var title = "List view: full variable set categorized according to " + varCategories[this.id].description + showList(title,variables,nodeMenu) + }) + } + //aigner: Set width of the div, so the VISTOMS dropdown (in the top of the page) still works + //#################################################################################################################### d3.select(".dataModelDiv").moveToBack() headerDiv.moveToBack() + d3.select(".addButtonDiv").moveToBack() d3.select(".navigationBarDiv").moveToBack() d3.select(".visPackDiv").moveToBack()