Mercurial > hg > NetworkVis
changeset 32:acc60a20582c
Temporary Changes for querybuilder. Selecting attribute and having results list filter not fully working yet. Need 'ALL' option in attributes.
author | arussell |
---|---|
date | Sat, 19 Dec 2015 09:15:43 -0500 |
parents | 5384b71df52a |
children | 758a5313baf4 |
files | query_builder/querybuild.html |
diffstat | 1 files changed, 162 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/query_builder/querybuild.html Thu Dec 10 07:26:40 2015 -0500 +++ b/query_builder/querybuild.html Sat Dec 19 09:15:43 2015 -0500 @@ -7,10 +7,12 @@ <link rel="stylesheet" href="select2-4.0.1/dist/css/select2.min.css"> <script type="text/javascript" src="js/d3.min.js"></script> + <script type="text/javascript" src="js/underscore-min.js"></script> <script type="text/javascript" src="select2-4.0.1/vendor/jquery-2.1.0.js"></script> <script type="text/javascript" src="select2-4.0.1/dist/js/select2.full.min.js"></script> + </head> <body style="background:none;"> <div role="navigation" class="navbar navbar-default navbar-static-top"> @@ -49,7 +51,7 @@ <div class="row" id="startrow" style="margin-top: 15px"> <div class="col-sm-4 col-md-4" id="select-col1"> <select class="selected-object form-control"> - <option selected>Selected object is: </option> + <option selected>Object type : </option> </select> </div> <div class="col-sm-4 col-md-4" id="select-col2"> @@ -57,6 +59,10 @@ <option selected>TEXT</option> <option>WITNESS</option> <option>PERSON</option> + <option>CODEX</option> + <option>PLACE</option> + <option>REPOSITORY</option> + <option>COLLECTION</option> </select> </div> </div> @@ -105,17 +111,20 @@ var sourceType = "TEXT"; var targets = []; var targetTypes = []; - var listTolerance = 100; + var targetObj = []; // The current objects on the display box var numFilters = 1; var filters = [ { id: 0, text: 'has relation' }, - { id: 1, text: 'attribute contains' } + { id: 1, text: 'attribute' } ]; $(".filter-box"+numFilters).select2({ // Initialize first filter box data: filters, minimumResultsForSearch: Infinity }); + var listTolerance = 100; + //$("") + function filter_html(n) { return '<div class="row" id="row'+n+'" style="margin-top: 15px">' + '<div class="col-sm-4 col-md-4" id="'+n+'filter-col1">' + @@ -127,31 +136,36 @@ } function constraint_html(classn) { return '<div class="col-sm-4 col-md-4" id="'+classn+'filter-col2">' + - '<select class="constraint-box'+classn+' form-control" >' + + '<select class="rel-constraint-box'+classn+' form-control" >' + + '</select>' + + '</div>'; + } + function attr_constraint_html(classn) { + return '<div class="col-sm-4 col-md-4" id="'+classn+'filter-col2">' + + '<select class="attr-constraint-box'+classn+' form-control" >' + '</select>' + '</div>'; } function submit_html(classn) { - return '<div class="col-sm-4 col-md-4" id="'+classn+'filter-col2">' + + return '<div class="col-sm-4 col-md-4" id="'+classn+'filter-col3">' + '<div class="form-group'+classn+'">' + - '<textarea class="form-control" rows="1" id="attribute-text-search'+classn+'">' + - '</textarea>' + + '<form onsubmit="return false;"> ' + + '<input type="text" name="attr-field" class="form-control" id="attr-input'+classn+'">' + + '</input>' + + '</form>' + '</div>' + '</div>'; } - function select_html(selection) { - return '<div class="row" id="startrow" style="margin-top: 15px">' + + function select_html(selection, n) { + return '<div class="row" id="row'+n+'" style="margin-top: 15px">' + '<div class="col-sm-4 col-md-4" id="select-col1"> ' + '<select class="selected-object form-control"> ' + '<option selected>Selected object is: </option> ' + '</select> ' + '</div> ' + '<div class="col-sm-4 col-md-4" id="select-col2"> ' + - '<select class="select-object1 form-control"> ' + - '<option selected>TEXT</option> ' + - '<option>WITNESS</option> ' + - '<option>PERSON</option> ' + - '</select> ' + + '<h4>' + selection + + '</h4>' + '</div> ' + '</div>'; } @@ -175,43 +189,44 @@ numFilters--; }); $("#results-container").dblclick(function() { - if ($("#results-container option:selected").length == 1) { - var selection = $(this).text(); - console.log("add filter"); - numFilters++; - $("#filters").append(select_html(selection, numFilters)); - // Generate inner relation list - genRelations(sourceType, ".constraint-box"+classnum); + var displayChoice = $("#results-container").find("option:selected").text(); + console.log(displayChoice + "........."); + var selection; + + _.map(targetObj, function(obj){ - } + if (_.values(_.values(targetObj))[1] === displayChoice) { + selection = (_.values(_.values(obj))[0])[1]; + } + else { + selection = (_.values(_.values(obj))[0])[0]; + } + }); + numFilters++; + $("#filters").append(select_html(selection, numFilters)); + // Generate inner relation list + //genRelations(sourceType, ".constraint-box"+numFilters); + sourceType = selection; console.log("add filter"); }); + $(function() { + $("input").submit(function(event, data) { + console.log($('.form-control').find("option:selected").text()); + console.log(event); + console.log(data); + event.preventDefault(); + + }); + }); - - - // For use in the onchange events below - function genRelations(sourceNodeType, constraintBox) { - var query = "match (source:"+sourceNodeType+")-[rel]-target return distinct rel.type"; - ajax1(query, constraintBox); - } - function genResults(sourceNodeType, selected, constraintBox) { - var query = "match (source:"+sourceNodeType+")-["+selected+"]-(target) return target.label, target.type"; - ajax1(query, constraintBox); - } - // Can be used to return a list of all available attributes - // TODO: Not implemented - function genAttributes(sourceNodeType, constraintBox) { - var query = "match (n:"+sourceNodeType+") with keys(n) as collection unwind collection as attributes return distinct attributes"; - ajax1(query, constraintBox); - } - // Change Events $('body').on('change', function(event){ var classname = (event.target.className).substr(0, (event.target.className).indexOf(" ")); - var classnum = (event.target.className.match(/\d+\.\d+|\d+\b|\d+(?=\w)/g) || [] ) - .map(function (v) {return +v;}).shift(); - var selectedOption = $('.'+classname+' option:selected').text(); + var classnum = (event.target.className.match(/\d+\.\d+|\d+\b|\d+(?=\w)/g) || [] ).map(function (v) {return +v;}).shift(); + var allclass = '.'+classname; + var selectedOption = $(allclass).find('option:selected').text(); + console.log("SEL "+ selectedOption); // Change is on the filter box if (classname.indexOf("filter-box") > -1) { @@ -220,40 +235,121 @@ $("#"+classnum+"filter-col2").remove(); $("#row"+classnum).append(constraint_html(classnum)); // Generate inner relation list - genRelations(sourceType, ".constraint-box"+classnum); + genRelations(sourceType, ".rel-constraint-box"+classnum); } - if (selectedOption === "attribute contains") { + if (selectedOption === "attribute") { $("#"+classnum+"filter-col2").remove(); + $("#row"+classnum).append(attr_constraint_html(classnum)); + genAttributes(sourceType, ".attr-constraint-box"+classnum); + //$("#row"+classnum).append(submit_html(classnum)); $("#row"+classnum).append(submit_html(classnum)); - //genAttributes(sourceType, ".constraint-box"+classnum); + } + + // NOT IMPLEMENTED + /* if (selectedOption === "return") { $("#"+classnum+"filter-col2").remove(); $("#row"+classnum).append(constraint_html(classnum)); genAttributes(targetTypes, ".constraint-box"+classnum); } + */ } // Change is on the relationship constraint box - if (classname.indexOf("constraint-box") > -1) { + if (classname.indexOf("rel-constraint-box") > -1) { //$().remove(); genResults(sourceType, selectedOption, "results-container"); } - // TODO: if the select object is changed update the sourceType var that we are looking at + // Change is on the attr constraint box + if (classname.indexOf("attr-constraint-box") > -1) { + //$().remove(); + console.log("CHANGE ON ATTR"); + console.log("changing currentqueryattr to" + selectedOption); + currentQueryAttr = selectedOption; + console.log("currentQueryAttr is" + currentQueryAttr); + //genResults(sourceType, selectedOption, "results-container"); + } + // Change is on subject scope if (classname.indexOf("select-object") > -1) { + sourceType = selectedOption; + console.log("CHANGE ON SCOPE"); + genResults(sourceType, "New Source", "results-container"); //ajax1(query, "results-container") } }); + $("#filters").submit(function (event) { + var inputId = $("input:text[name=attr-field]")[0].id; + var inputValue = $("input:text[name=attr-field]").val(); + // Alter results list + console.log("QUERY TYPE IS ATTRIBUTE NOW"); + currentQueryType = "attribute"; + console.log("SUBMITTED"); + genResults(sourceType, inputValue, "results-container") + }); + // For use in the onchange events above + function genRelations(sourceNodeType, constraintBox) { + console.log("GENERATE ALL RELATIONS"); + var query = "match (source:"+sourceNodeType+")-[rel]-target return distinct rel.type"; + console.log("QUERY TYPE IS RELATION NOW"); + currentQueryType = "relation"; + ajax1(query, constraintBox); + } + function genAttributes(sourceNodeType, constraintBox) { + console.log("GENERATE ALL ATTRIBUTES"); + var query = "match (n:"+sourceNodeType+") with keys(n) as collection unwind collection as attributes return distinct attributes"; + ajax1(query, constraintBox); + } + function genResults(sourceNodeType, selected, constraintBox) { + // TODO: Return first the list of current values of the display box + + if (selected === "New Source") { + console.log("NEW SOURCE - UPDATE RESULTS"); + var query = "match (source:"+sourceNodeType+") return source._n_label, source.type"; + } + else if (currentQueryType === "attribute") { + console.log("ATTR CHANGE - UPDATE RESULTS"); + console.log("before update currentQueryAttr is " + currentQueryAttr); + var qAttr = currentQueryAttr; + var query = "match (source:"+sourceNodeType+") where "+get_result_labels()+" AND source."+qAttr+"=~\"(?i).*"+selected+".*\" return distinct source._n_label, source.type limit 5"; + console.log(query); + } + else if (currentQueryType === "relation") { + var query = "match (source:" + sourceNodeType + ")-[rel:" + selected + "]->(target) return distinct target._n_label, target.type"; + console.log("REL CHANGE - UPDATE RESULTS"); + } + else { + console.log("GENRESULTS IMPROPERLY CALLED"); + return; + } + ajax1(query, constraintBox); + } + var currentQueryType; + var currentQueryAttr; + var resultLabelString = ""; + function get_result_labels() { + return resultLabelString; + } + function set_result_labels(currentResults) { + resultLabelString = "("; + for (var i = 0; i < currentResults.length; i++) { + if (i > 0) resultLabelString += " OR "; + resultLabelString += 'source._n_label=\"'+currentResults[i].text.substr(1)+'\"'; + } + resultLabelString += ")" + } + // to use contains + // TODO: start n = node(*) where n.Name =~ '.*SUBSTRING.*' return n.Name, n; + // Ajax request function function ajax1(q, resBox) { - console.log(q); $.ajaxSetup({ headers: { "Authorization": 'Basic ' + window.btoa("neo4j"+":"+"neo5j") @@ -301,7 +397,6 @@ // On success, generate new data // TODO: might want to just always return nodes and then deal with the queryData different for each type of return function dataGen(dataArr, resBox) { - console.log(dataArr); var d = dataArr; targets = []; @@ -318,12 +413,12 @@ var d = b.text.replace(/<|>/g, ''); return c.localeCompare(d); }); - console.log(queryData[0].text); // Change the displayed results if (resBox === "results-container") { process_display_results(queryData); } + // Or fill any select boxes else { $(resBox).select2({ data: queryData @@ -334,16 +429,31 @@ var weights = []; var resultLength = queryData.length; targetTypes = []; - + targetObj = queryData; + set_result_labels(queryData); $('#results-container') .find('option') .remove() .end() ; + for (var i = 0; i < targets.length; i++) { + if (targetTypes.indexOf(targets[i]) == -1) { + targetTypes.push(targets[i]); + weights.push(1); + } + else { + weights[targetTypes.indexOf(targets[i])] += 1; + } + } if (resultLength < listTolerance) { for (var i = 0; i < resultLength; i++) { // TODO: put this jQuery call into its own function to be called if the else statement occurs // TODO: but the user actually does want to see the entire huge list. + // This next bit removes duplicate labels if we want to use that for things like cities + // would this throw issues with other things?? + //$('#results-container option:contains('+queryData[i].text+')').each(function(){ + // $(this).remove(); + //}); $('#results-container') .append($("<option></option>") .attr("value", i) @@ -351,15 +461,6 @@ } } else { - for (var i = 0; i < targets.length; i++) { - if (targetTypes.indexOf(targets[i]) == -1) { - targetTypes.push(targets[i]); - weights.push(1); - } - else { - weights[targetTypes.indexOf(targets[i])] += 1; - } - } for (var i = 0; i < targetTypes.length; i++) { $('#results-container') .append($("<option></option>")