xref: /petsc/share/petsc/saws/js/PETSc.js (revision 0ec0a084dafaf19d7cb029f108202517fa408668)
1//
2//  Contains methods from SAWs.js but modified to display in a PETSc specific way
3
4PETSc = {};
5
6//this variable is used to organize all the data from SAWs
7var sawsInfo = {};
8
9//record if initialized the page (added appropriate divs for the diagrams and such)
10var init = false;
11
12//record what iteration we are on (remove text on second iteration)
13var iteration = 0;
14
15//holds the colors used in the tree drawing
16var colors = ["black","red","blue","green"];
17
18//This Function is called once (document).ready. The javascript for this was written by the PETSc code into index.html
19PETSc.getAndDisplayDirectory = function(names,divEntry){
20
21    if(!init) {
22        $("head").append('<script src="js/parsePrefix.js"></script>');//reuse the code for parsing thru the prefix
23        $("head").append('<script src="js/recordSawsData.js"></script>');//reuse the code for organizing data into sawsInfo
24        $("head").append('<script src="js/utils.js"></script>');//necessary for the two js files above
25        $("head").append('<script src="js/drawDiagrams.js"></script>');//contains the code to draw diagrams of the solver structure. in particular, fieldsplit and multigrid
26        $("head").append('<script src="js/boxTree.js"></script>');//contains the code to draw the tree
27        $("head").append('<script src="js/getCmdOptions.js"></script>');//contains the code to draw the tree
28        $("body").append("<div id=\"tree\" align=\"center\" style=\"background-color:#90C7E3\"></div");
29        $("body").append("<div id=\"leftDiv\" style=\"float:left;\"></div>");
30        $(divEntry).appendTo("#leftDiv");
31        $("body").append("<div id=\"diagram\"></div>");
32
33        init = true;
34    }
35
36    jQuery(divEntry).html("");
37    SAWs.getDirectory(names,PETSc.displayDirectory,divEntry);
38}
39
40PETSc.displayDirectory = function(sub,divEntry)
41{
42    globaldirectory[divEntry] = sub;
43
44    iteration ++;
45    if(iteration == 2) { //remove text
46        for(var i=0; i<9; i++) {
47            $("body").children().first().remove();
48        }
49    }
50
51    if($("#leftDiv").children(0).is("center")) //remove the title of the options if needed
52        $("#leftDiv").children().get(0).remove();
53
54    console.log(sub);
55
56    if(sub.directories.SAWs_ROOT_DIRECTORY.directories.PETSc.directories != undefined) {
57
58        recordSawsData(sawsInfo,sub); //records data into sawsInfo
59
60        if (sub.directories.SAWs_ROOT_DIRECTORY.directories.PETSc.directories.Options.variables._title.data == "Preconditioner (PC) options" || sub.directories.SAWs_ROOT_DIRECTORY.directories.PETSc.directories.Options.variables._title.data == "Krylov Method (KSP) options") {
61
62            var SAWs_prefix = sub.directories.SAWs_ROOT_DIRECTORY.directories.PETSc.directories.Options.variables["prefix"].data[0];
63
64            if(SAWs_prefix == "(null)")
65                SAWs_prefix = "";
66
67            $("#diagram").html("");
68            var data = drawDiagrams(sawsInfo,"0",parsePrefix(sawsInfo,SAWs_prefix).endtag,5,5);
69
70            if(data != "") {
71                //$("#diagram").html("<svg id=\"svgCanvas\" width='700' height='700' viewBox='0 0 2000 2000'>"+data+"</svg>");
72                $("#diagram").html("<svg id=\"svgCanvas\" width=\"" + sawsInfo["0"].x_extreme/4 + "\" height=\"" + sawsInfo["0"].y_extreme/4 + "\" viewBox=\"0 0 " + sawsInfo["0"].x_extreme + " " +sawsInfo["0"].y_extreme + "\">"+data+"</svg>");
73                //IMPORTANT: Viewbox determines the coordinate system for drawing. width and height will rescale the SVG to the given width and height. Things should NEVER be appended to an svg element because then we would need to use a hacky refresh which works in Chrome, but no other browsers that I know of.
74            }
75            calculateSizes(sawsInfo,"0");
76            var svgString = getBoxTree(sawsInfo,"0",0,0);
77            $("#tree").html("<svg id=\"treeCanvas\" align=\"center\" width=\"" + sawsInfo["0"].total_size.width + "\" height=\"" + sawsInfo["0"].total_size.height + "\" viewBox=\"0 0 " + sawsInfo["0"].total_size.width + " " + sawsInfo["0"].total_size.height + "\">" + svgString + "</svg>");
78        }
79    }
80    PETSc.displayDirectoryRecursive(sub.directories,divEntry,0,"");//this method is recursive on itself and actually fills the div with text and dropdown lists
81
82    if (sub.directories.SAWs_ROOT_DIRECTORY.variables.hasOwnProperty("__Block") && (sub.directories.SAWs_ROOT_DIRECTORY.variables.__Block.data[0] == "true")) {
83        jQuery(divEntry).after("<input type=\"button\" value=\"Continue\" id=\"continue\">");
84        $("#continue").after("<input type=\"button\" value=\"Finish\" id=\"finish\">");
85        jQuery('#continue').on('click', function(){
86            $("#continue").remove();//remove self immediately
87            $("#finish").remove();
88            SAWs.updateDirectoryFromDisplay(divEntry);
89            sub.directories.SAWs_ROOT_DIRECTORY.variables.__Block.data = ["false"];
90            SAWs.postDirectory(sub);
91            window.setTimeout(PETSc.getAndDisplayDirectory,1000,null,divEntry);
92        });
93        jQuery('#finish').on('click', function(){
94            $("#finish").remove();//remove self immediately
95            $("#continue").remove();
96            SAWs.updateDirectoryFromDisplay(divEntry);
97            sub.directories.SAWs_ROOT_DIRECTORY.variables.__Block.data = ["false"];
98            sub.directories.SAWs_ROOT_DIRECTORY.directories.PETSc.directories.Options.variables.StopAsking.data = ["true"];//this is hardcoded (bad)
99            SAWs.postDirectory(sub);
100            window.setTimeout(PETSc.getAndDisplayDirectory,1000,null,divEntry);
101        });
102    } else console.log("no block property or block property is false");
103}
104
105
106/*
107 * This function appends DOM elements to divEntry based on the JSON data in sub
108 *
109 */
110
111PETSc.displayDirectoryRecursive = function(sub,divEntry,tab,fullkey)
112{
113    jQuery.each(sub,function(key,value){
114        fullkey = fullkey+key;//key contains things such as "PETSc" or "Options"
115        if(jQuery("#"+fullkey).length == 0){
116            jQuery(divEntry).append("<div id =\""+fullkey+"\"></div>")
117            if (key != "SAWs_ROOT_DIRECTORY") {
118                //SAWs.tab(fullkey,tab);
119	        //jQuery("#"+fullkey).append("<b>"+ key +"<b><br>");//do not display "PETSc" nor "Options"
120            }
121
122            var descriptionSave = "";//saved description string because although the data is fetched: "description, -option, value" we wish to display it: "-option, value, description"
123            var manualSave = ""; //saved manual text
124            var mg_encountered = false;//record whether or not we have encountered pc=multigrid
125
126            jQuery.each(sub[key].variables, function(vKey, vValue) {//for each variable...
127
128                if (vKey.substring(0,2) == "__") // __Block variable
129                    return;
130                //SAWs.tab(fullkey,tab+1);
131                if (vKey[0] != '_') {//this chunk of code adds the option name
132                    if(vKey.indexOf("prefix") != -1 && sub[key].variables[vKey].data[0] == "(null)")
133                        return;//do not display (null) prefix
134
135                    if(vKey.indexOf("prefix") != -1) //prefix text
136                        $("#"+fullkey).append(vKey + ":&nbsp;");
137                    else if(vKey.indexOf("ChangedMethod") == -1 && vKey.indexOf("StopAsking") == -1) { //options text
138                        //options text is a link to the appropriate manual page
139
140                        var manualDirectory = "all"; //this directory does not exist yet so links will not work for now
141                        $("#"+fullkey).append("<br><a href=\"http://www.mcs.anl.gov/petsc/petsc-dev/manualpages/" +  manualDirectory + "/" + manualSave + ".html\" title=\"" + descriptionSave + "\" id=\"data"+fullkey+vKey+j+"\">"+vKey+"&nbsp</a>");
142                    }
143                }
144
145                for(j=0;j<sub[key].variables[vKey].data.length;j++){//vKey tells us a lot of information on what the data is. data.length is 1 most of the time. when it is more than 1, that results in 2 input boxes right next to each other
146
147                    if(vKey.indexOf("man") != -1) {//do not display manual, but record the text
148                        manualSave = sub[key].variables[vKey].data[j];
149                        continue;
150                    }
151
152                    if(vKey.indexOf("title") != -1) {//display title in center
153                        $("#"+"leftDiv").prepend("<center>"+"<span style=\"font-family: Courier\" size=\""+(sub[key].variables[vKey].data[j].toString().length+1)+"\" id=\"data"+fullkey+vKey+j+"\">"+sub[key].variables[vKey].data[j]+"</span>"+"</center>");//used to be ("#"+fullkey).append
154                        continue;
155                    }
156
157                    if(sub[key].variables[vKey].alternatives.length == 0) {//case where there are no alternatives
158                        if(sub[key].variables[vKey].dtype == "SAWs_BOOLEAN") {
159                            $("#"+fullkey).append("<select id=\"data"+fullkey+vKey+j+"\">");//make the boolean dropdown list.
160                            $("#data"+fullkey+vKey+j).append("<option value=\"true\">True</option> <option value=\"false\">False</option>");
161                            if(vKey == "ChangedMethod" || vKey == "StopAsking") {//do not show changedmethod nor stopasking to user
162                                $("#data"+fullkey+vKey+j).attr("hidden",true);
163                            }
164
165                        } else {
166                            if(sub[key].variables[vKey].mtype != "SAWs_WRITE") {
167
168                                descriptionSave = sub[key].variables[vKey].data[j];
169
170                                if(vKey.indexOf("prefix") != -1) //data of prefix so dont do manual and use immediately
171                                    $("#"+fullkey).append("<a style=\"font-family: Courier\" size=\""+(sub[key].variables[vKey].data[j].toString().length+1)+"\" id=\"data"+fullkey+vKey+j+"\">"+sub[key].variables[vKey].data[j]+"</a><br>");
172
173                            }
174                            else {//can be changed (append dropdown list)
175                                $("#"+fullkey).append("<input type=\"text\" style=\"font-family: Courier\" size=\""+(sub[key].variables[vKey].data[j].toString().length+1)+"\" id=\"data"+fullkey+vKey+j+"\" name=\"data\" \\>");
176                            }
177                            jQuery("#data"+fullkey+vKey+j).keyup(function(obj) {
178                                console.log( "Key up called "+key+vKey );
179                                sub[key].variables[vKey].selected = 1;
180                                $("#data"+fullkey+"ChangedMethod0").find("option[value='true']").attr("selected","selected");//set changed to true automatically
181                            });
182                        }
183                        jQuery("#data"+fullkey+vKey+j).val(sub[key].variables[vKey].data[j]);//set val from server
184                        if(vKey != "ChangedMethod") {
185                            jQuery("#data"+fullkey+vKey+j).change(function(obj) {
186                                sub[key].variables[vKey].selected = 1;
187                                $("#data"+fullkey+"ChangedMethod0").find("option[value='true']").attr("selected","selected");//set changed to true automatically
188                            });
189                        }
190                    } else {//case where there are alternatives
191                        jQuery("#"+fullkey).append("<select id=\"data"+fullkey+vKey+j+"\">");
192                        jQuery("#data"+fullkey+vKey+j).append("<option value=\""+sub[key].variables[vKey].data[j]+"\">"+sub[key].variables[vKey].data[j]+"</option>");
193                        for(var l=0;l<sub[key].variables[vKey].alternatives.length;l++) {
194                            jQuery("#data"+fullkey+vKey+j).append("<option value=\""+sub[key].variables[vKey].alternatives[l]+"\">"+sub[key].variables[vKey].alternatives[l]+"</option>");
195                        }
196                        jQuery("#"+fullkey).append("</select>");
197
198                        jQuery("#data"+fullkey+vKey+j).change(function(obj) {
199                            sub[key].variables[vKey].selected = 1;
200                            $("#data"+fullkey+"ChangedMethod0").find("option[value='true']").attr("selected","selected");//set changed to true automatically
201                            var id = "data"+fullkey+vKey+j;
202                            if(id.indexOf("type") != -1) {//if some type variable changed, then act as if continue button was clicked
203                                $("#continue").trigger("click");
204                            }
205                        });
206                    }
207                }
208            });
209
210            if(typeof sub[key].directories != 'undefined'){
211                PETSc.displayDirectoryRecursive(sub[key].directories,divEntry,tab+1,fullkey);
212             }
213        }
214    });
215}
216