src/widgets/KnowledgeConcierge.js
changeset 983 97fef7a4b189
parent 982 cfcbac34d020
child 984 e034099276f6
equal deleted inserted replaced
982:cfcbac34d020 983:97fef7a4b189
    11     sketch_files: [ "tmgraph.pde", "physics.pde", "model.pde", "javascript.pde", "menu.pde", "event.pde", "constants.pde", "initialdata.pde"],
    11     sketch_files: [ "tmgraph.pde", "physics.pde", "model.pde", "javascript.pde", "menu.pde", "event.pde", "constants.pde", "initialdata.pde"],
    12     kc_api_root: "/kn-concierge/",
    12     kc_api_root: "/kn-concierge/",
    13     related_api_endpoint: "",
    13     related_api_endpoint: "",
    14     use_word_boundaries: false,
    14     use_word_boundaries: false,
    15     related_data_type: 'json', // SET TO "jsonp" FOR CROSS-DOMAIN OPERATION
    15     related_data_type: 'json', // SET TO "jsonp" FOR CROSS-DOMAIN OPERATION
    16     related_count: 8
    16     related_count: 8,
    17 }
    17 }
    18 
    18 
    19 IriSP.Widgets.KnowledgeConcierge.prototype.messages = {
    19 IriSP.Widgets.KnowledgeConcierge.prototype.messages = {
    20     "fr": {
    20     "fr": {
    21         related_videos: "Vidéos liées",
    21         related_videos: "Vidéos liées",
    22         duration_: "Durée :"
    22         duration_: "Durée :",
       
    23         for_keywords_: "pour le(s) mots-clé(s) :"
    23     },
    24     },
    24     "en": {
    25     "en": {
    25         related_videos: "Related Videos",
    26         related_videos: "Related Videos",
    26         duration_: "Duration:"
    27         duration_: "Duration:",
       
    28         for_keywords_: "for keyword(s):"
    27     }
    29     }
    28 }
    30 }
    29 
    31 
    30 IriSP.Widgets.KnowledgeConcierge.prototype.template =
    32 IriSP.Widgets.KnowledgeConcierge.prototype.template =
    31     '<div class="Ldt-Kc-Slider"></div><canvas class="Ldt-Kc-Canvas" />'
    33     '<div class="Ldt-Kc-Slider"></div><canvas class="Ldt-Kc-Canvas" />'
    32     + '<div class="Ldt-Kc-Waiting"></div>'
    34     + '<div class="Ldt-Kc-Waiting"></div>'
    33     + '<div class="Ldt-Kc-Related"><h2>{{ l10n.related_videos }}</h2>'
    35     + '<div class="Ldt-Kc-Related"><h2>{{ l10n.related_videos }}</h2>'
       
    36     + '<h3 class="Ldt-Kc-For-Keywords">{{l10n.for_keywords_}} <span class="Ldt-Kc-Keywords"></span></h3>'
    34     + '<div class="Ldt-Kc-Related-List"></div></div>';
    37     + '<div class="Ldt-Kc-Related-List"></div></div>';
    35 
    38 
    36 IriSP.Widgets.KnowledgeConcierge.prototype.draw = function() {
    39 IriSP.Widgets.KnowledgeConcierge.prototype.draw = function() {
    37     this.renderTemplate();
    40     this.renderTemplate();
    38     var _canvasHeight = this.height - 16,
    41     var _canvasHeight = this.height - 16,
    52     var _this = this,
    55     var _this = this,
    53         _pjsfiles = IriSP._(this.sketch_files).map(function(_f) { return _this.sketch_path + "/" + _f }),
    56         _pjsfiles = IriSP._(this.sketch_files).map(function(_f) { return _this.sketch_path + "/" + _f }),
    54         _selectedText = "",
    57         _selectedText = "",
    55         currentNodesList = "",
    58         currentNodesList = "",
    56         relatedCache = {},
    59         relatedCache = {},
       
    60         relatedRequests = {},
    57         relatedTemplate = '<div class="Ldt-Kc-Related-Item"><a href="{{ widget.video_url_base }}{{ media.iri_id }}"><img src="{{ media.image }}"></a>'
    61         relatedTemplate = '<div class="Ldt-Kc-Related-Item"><a href="{{ widget.video_url_base }}{{ media.iri_id }}"><img src="{{ media.image }}"></a>'
    58             + '<h3><a href="{{ widget.video_url_base }}{{ media.iri_id }}">{{ media.title }}</a></h3><p>{{ description }}</p>'
    62             + '<h3><a href="{{ widget.video_url_base }}{{ media.iri_id }}">{{ media.title }}</a></h3><p>{{ description }}</p>'
    59             + '<p>{{ widget.l10n.duration_ }} <span class="Ldt-Kc-Item-Duration">{{ duration }}</span></p>'
    63             + '<p>{{ widget.l10n.duration_ }} <span class="Ldt-Kc-Item-Duration">{{ duration }}</span></p>'
    60             + '</a><div class="Ldt-Kc-Clearer"></div></div>';
    64             + '</a><div class="Ldt-Kc-Clearer"></div></div>';
    61             
    65             
    62     Processing.loadSketchFromSources(_canvas[0],_pjsfiles);
    66     Processing.loadSketchFromSources(_canvas[0],_pjsfiles);
    63     
    67     
    64     function renderRelated(keywords) {
    68     function renderRelated() {
       
    69         var keywords = currentNodesList;
       
    70         if (typeof relatedCache[keywords] === "undefined") {
       
    71             return;
       
    72         }
    65         _this.$.find(".Ldt-Kc-Waiting").hide();
    73         _this.$.find(".Ldt-Kc-Waiting").hide();
    66         if (relatedCache[keywords].length) {
    74         if (relatedCache[keywords].length) {
       
    75             _this.$.find(".Ldt-Kc-Keywords").html(keywords.replace(/\,/g,", "));
    67             var _html = '<div class="Ldt-Kc-Row">';
    76             var _html = '<div class="Ldt-Kc-Row">';
    68             IriSP._(relatedCache[keywords]).each(function(media, i) {
    77             IriSP._(relatedCache[keywords]).each(function(media, i) {
    69                 var _tmpldata = {
    78                 var _tmpldata = {
    70                     widget: _this,
    79                     widget: _this,
    71                     media: media,
    80                     media: media,
    85         }
    94         }
    86     }    
    95     }    
    87 
    96 
    88     function triggerSearch(text) {
    97     function triggerSearch(text) {
    89         if (_selectedText !== text) {
    98         if (_selectedText !== text) {
    90             //console.log("Trigger search for '" + text + "'");
       
    91             _selectedText = text;
    99             _selectedText = text;
    92             _this.player.trigger("search.triggeredSearch", text);
   100             _this.source.getAnnotations().search(text);
    93         }
   101         }
    94     }
   102     }
    95     
   103     
    96     function searchNodes(tags) {
   104     function searchNodes(tags) {
    97         var _tlist = (_this.use_word_boundaries ? IriSP._(tags).map(function(t) { return "\\\\y" + t + "\\\\y" }) : tags),
   105         var _tlist = (_this.use_word_boundaries ? IriSP._(tags).map(function(t) { return "\\\\y" + t + "\\\\y" }) : tags),
   117                         _fns.countassoc(node.id, node.proj);
   125                         _fns.countassoc(node.id, node.proj);
   118                         if (l > 1) {
   126                         if (l > 1) {
   119                             node.position(Math.floor(radius*Math.sin(2 * Math.PI * i / l)),Math.floor(radius*Math.cos(2 * Math.PI * i / l)));
   127                             node.position(Math.floor(radius*Math.sin(2 * Math.PI * i / l)),Math.floor(radius*Math.cos(2 * Math.PI * i / l)));
   120                         }
   128                         }
   121                     }
   129                     }
   122                 } else {
       
   123                     console.log("No match found");
       
   124                 }
   130                 }
   125             }
   131             }
   126         );
   132         );
   127     }
   133     }
   128     
   134     
   129     function listNodes() {
   135     function showRelated(nodetexts) {
   130         var nodes = _pjs.getNodes().values().toArray(),
   136         currentNodesList = nodetexts;
   131             nodetexts = IriSP._(nodes).chain().pluck("name").sortBy().value().join(",");
   137         if (typeof relatedCache[nodetexts] === "undefined") {
   132         if (currentNodesList !== nodetexts) {
   138             _this.$.find(".Ldt-Kc-Waiting").show();
   133             if (typeof relatedCache[nodetexts] === "undefined") {
   139             _this.$.find(".Ldt-Kc-Related").hide();
   134                 _this.$.find(".Ldt-Kc-Waiting").show();
   140             if (relatedRequests[nodetexts]) {
   135                 _this.$.find(".Ldt-Kc-Related").hide();
   141                 return;
   136                 IriSP.jQuery.ajax({
   142             }
   137                     url: _this.related_api_endpoint,
   143             relatedRequests[nodetexts] = true;
   138                     data: {
   144             IriSP.jQuery.ajax({
   139                         format: _this.related_data_type,
   145                 url: _this.related_api_endpoint,
   140                         keywords: nodetexts
   146                 data: {
   141                     },
   147                     format: _this.related_data_type,
   142                     dataType: _this.related_data_type,
   148                     keywords: nodetexts
   143                     success: function(data) {
   149                 },
   144                         relatedCache[nodetexts] = IriSP._(data.objects)
   150                 dataType: _this.related_data_type,
   145                             .chain()
   151                 success: function(data) {
   146                             .filter(function(o) {
   152                     relatedCache[nodetexts] = IriSP._(data.objects)
   147                                 return o.iri_id !== _this.media.id;
   153                         .chain()
   148                             })
   154                         .filter(function(o) {
   149                             .sortBy(function(o) {
   155                             return o.iri_id !== _this.media.id;
   150                                 return - o.score;
   156                         })
   151                             })
   157                         .sortBy(function(o) {
   152                             .first(_this.related_count)
   158                             return - o.score;
   153                             .value();
   159                         })
   154                         renderRelated(nodetexts);
   160                         .first(_this.related_count)
   155                     }
   161                         .value();
   156                 })
   162                     renderRelated();
   157             } else {
   163                 }
   158                 renderRelated(nodetexts);
   164             })
   159             }
   165         } else {
   160             currentNodesList = nodetexts;
   166             renderRelated();
   161         }
   167         }
   162     }
   168     }
   163     
   169     
   164     function rootNode(id, proj) {
   170     function rootNode(id, proj) {
   165         jQuery.getJSON(
   171         jQuery.getJSON(
   171             function(response) {
   177             function(response) {
   172                 if (response != null && response.items.length > 0){
   178                 if (response != null && response.items.length > 0){
   173                     item = response.items[0];
   179                     item = response.items[0];
   174                     _pjs.initNode(item.id, item.name, item.grp, item.uid, item.proj);
   180                     _pjs.initNode(item.id, item.name, item.grp, item.uid, item.proj);
   175                     _fns.countassoc(item.id, item.proj);
   181                     _fns.countassoc(item.id, item.proj);
   176                 } else {
   182                 }
   177                     console.debug('No such topic.');
   183             }
   178                 }
   184         );
   179         });
       
   180     }
   185     }
   181     
   186     
   182     function bindJavascript() {
   187     function bindJavascript() {
   183         _pjs = Processing.getInstanceById(_tmpId);
   188         _pjs = Processing.getInstanceById(_tmpId);
   184         if (_pjs && typeof _pjs.bindJavascript === "function") {
   189         if (_pjs && typeof _pjs.bindJavascript === "function") {
   187                 _pjs.setSize(_canvasWidth,_canvasHeight);
   192                 _pjs.setSize(_canvasWidth,_canvasHeight);
   188                 var _edit = false,
   193                 var _edit = false,
   189                     _teamMode = true;
   194                     _teamMode = true;
   190                 _pjs.saveMode("en",false,_teamMode,false,"both",_edit);
   195                 _pjs.saveMode("en",false,_teamMode,false,"both",_edit);
   191                 rootNode(_this.topic_id, _this.project_id);
   196                 rootNode(_this.topic_id, _this.project_id);
   192                 _canvas.click(function() {
       
   193                     triggerSearch("")
       
   194                 });
       
   195                 _slider.slider({
   197                 _slider.slider({
   196                     min: -20,
   198                     min: -20,
   197                     max: 20,
   199                     max: 20,
   198                     value: 0,
   200                     value: 0,
   199                     range: "min",
   201                     range: "min",
   204             }, 1000);
   206             }, 1000);
   205         } else {
   207         } else {
   206             setTimeout(bindJavascript, 1000); 
   208             setTimeout(bindJavascript, 1000); 
   207         }
   209         }
   208     }
   210     }
   209     
   211     var currentSelection = null, lockMode = false;
   210     var _fns = {
   212     var _fns = {
   211         adjacentnodes: function(id, proj, adj, both) {
   213         adjacentnodes: function(id, proj, adj, both) {
   212             //console.log("Function adjacentnodes called with", arguments);
       
   213             jQuery.ajax({
   214             jQuery.ajax({
   214                 url: _this.kc_api_root + "associations-bd.jsp",
   215                 url: _this.kc_api_root + "associations-bd.jsp",
   215                 cache: false,
   216                 cache: false,
   216                 data: {
   217                 data: {
   217                     id: id,
   218                     id: id,
   234                             _pjs.setNodeValue(item.to_id,item.to_proj,  item.to_name,item.to_grp,item.to_abst,item.to_uid);
   235                             _pjs.setNodeValue(item.to_id,item.to_proj,  item.to_name,item.to_grp,item.to_abst,item.to_uid);
   235                             if (item.to_assoc!=null) {
   236                             if (item.to_assoc!=null) {
   236                                 _pjs.setNodeAssoc(item.to_id, item.to_proj, item.to_assoc);
   237                                 _pjs.setNodeAssoc(item.to_id, item.to_proj, item.to_assoc);
   237                             }
   238                             }
   238                         }
   239                         }
   239                         listNodes();
       
   240                         return response;
   240                         return response;
   241                     } else {
   241                     } else {
   242                         //.debug('No such topic.');
   242                         //.debug('No such topic.');
   243                         return null;
   243                         return null;
   244                     }
   244                     }
   245                 }
   245                 }
   246             });
   246             });
   247         },
   247         },
   248         setscale: function(scl){
   248         setscale: function(scl){
   249             //console.log("Function setscale called with", arguments);
       
   250             _slider.slider("value", 10*Math.log(scl));
   249             _slider.slider("value", 10*Math.log(scl));
   251         },
   250         },
   252         countassoc: function(id, proj) {
   251         countassoc: function(id, proj) {
   253             //console.log("Fonction countassoc called with", arguments);
       
   254             jQuery.ajax({
   252             jQuery.ajax({
   255                 url: _this.kc_api_root + "count-assoc.jsp",
   253                 url: _this.kc_api_root + "count-assoc.jsp",
   256                 data: {
   254                 data: {
   257                     id: id,
   255                     id: id,
   258                     proj: proj
   256                     proj: proj
   263                             item = response.items[i];
   261                             item = response.items[i];
   264                             _pjs.setNodeValue(item.id, item.proj, item.name, item.grp, item.abst);
   262                             _pjs.setNodeValue(item.id, item.proj, item.name, item.grp, item.abst);
   265                             if (item.assoc!=null) _pjs.setNodeAssoc(item.id, item.proj, item.assoc);
   263                             if (item.assoc!=null) _pjs.setNodeAssoc(item.id, item.proj, item.assoc);
   266                             if (item.mass!=null) _pjs.setNodeMass( item.id, item.proj, item.mass);
   264                             if (item.mass!=null) _pjs.setNodeMass( item.id, item.proj, item.mass);
   267                         }
   265                         }
   268                     } else {
       
   269                         console.debug('No such topic.');
       
   270                     }
   266                     }
   271                 }
   267                 }
   272             });
   268             });
   273         },
   269         },
   274         new_select: function(id, proj) {
   270         username: function() {
   275             var node = _pjs.findNode(id, proj);
   271             var nodes = _pjs.getNodes().values().toArray(),
   276             triggerSearch(node.name);
   272                 nodetexts = IriSP._(nodes).chain().pluck("name").sortBy().value().join(",");
   277             //console.log("Mouse over node named '" + node.name + "'");
   273             showRelated(nodetexts);
   278         },
   274         },
   279         username: listNodes
   275         mousemove: function(selection) {
       
   276             if (selection !== currentSelection) {
       
   277                 if (selection && !lockMode) {
       
   278                     triggerSearch(selection.name);
       
   279                 }
       
   280                 currentSelection = selection;
       
   281             }
       
   282         },
       
   283         click: function(selection) {
       
   284             if (selection) {
       
   285                 lockMode = true;
       
   286                 triggerSearch(selection.name);
       
   287                 showRelated(selection.name);
       
   288             } else {
       
   289                 lockMode = false;
       
   290                 triggerSearch()
       
   291             }
       
   292         }
   280     }
   293     }
   281     var uselessfuncts = [
   294     var uselessfuncts = [
   282         "selectnode", "selectedge", "topicnode","group_shapes",
   295         "selectnode", "selectedge", "topicnode","group_shapes",
   283         "allbackup", "allretrieve", "new_topic", "pedia", "set_mode",
   296         "allbackup", "allretrieve", "new_topic", "pedia", "set_mode",
   284         "new_relation", "startexpand", "endexpand" //, "username"
   297         "new_relation", "startexpand", "endexpand", "new_select" //, "mouseover" //, "username"
   285     ];
   298     ];
   286     
   299     
   287     IriSP._(uselessfuncts).each(function(funcname) {
   300     IriSP._(uselessfuncts).each(function(funcname) {
   288         _fns[funcname] = function() {
   301         _fns[funcname] = function() {
   289 //            console.log("Function", funcname, "called with arguments", arguments);
   302 //            console.log("Function", funcname, "called with arguments", arguments);