2011-04-12 62 views
1

我正在使用this arbor fork製作semanticproxy.com數據的Force Directed Graph。我有一個控制節點(以下略)主Explorer對象:

function Explorer(canvas) { 
    // set up particle system 
    this.ps = arbor.ParticleSystem(1000, 600, 0.5); 
    this.ps.renderer = Renderer(canvas); 
    this.canvas = $(canvas).get(0); 

    var self = this; 

    $('body').bind('subjectFound', function(event, sourceNode, targetName, targetRelevance) { 
    self.addEdge(sourceNode, targetName, targetRelevance); 
    }); 
} 

Explorer.prototype.addEdge = function(source, target, relevance) { 
    var target = this.ps.addNode(target); 
    if (source != target) this.ps.addEdge(source, target, {relevance:relevance}); 
} 

// start the explorer up on a new subject 
Explorer.prototype.start = function(name) { 
    var node = this.ps.addNode(name); 
    node.populate(this.ps); 
}; 

var xplor = new Explorer("#viewport"); 
xplor.start("Andreas Michl"); 

你會發現,start()方法添加一個節點到粒子系統(偉大工程),然後填充該節點。下面是該節點的代碼,這部分(請注意,我的增強節點arbor.js原型):

// fills this node with data from SemanticProxy 
Node.prototype.populate = function() { 
    var self = this; 

    // get the semantic data for this subject  
    // setup the handler function 
    var functionName = "subjectHandler" + new Date().getTime(); 
    window[functionName] = function(data) { 
    // invoke function with saved context and parameter  
    self._fillFromSP.call(self, data);  
    } 
    var url = "http://service.semanticproxy.com/processurl/"+SP_KEY+"/jsonp:"+functionName+"/http://en.wikipedia.org/wiki/"+this.name; 
    $.ajax({url: url, dataType: "script", type: "GET", cache: false, callback: null, data: null}); 
}; 

// fills this subject with data from SemanticProxy 
Node.prototype._fillFromSP = function(data) { 
    var self = this; 
    $.each(data, function(key, val) { 
    if (key != "doc") { 
     if (val.name && val.relevance) { 
     $('body').triggerHandler('subjectFound', [self, val.name, val.relevance]); 
     } 
    } 
    }); 
} 

因此,一旦返回semanticproxy數據應該觸發「subjectFound」處理程序在資源管理器對象並添加一個節點,就像之前對第一個節點所做的那樣。但它每次都會窒息 - 圖表鎖定,我的一個cpu核心的使用率達到100%(Firefox和Chrome)。

但是,如果我改變填入方法如下,它工作正常:

Node.prototype.populate = function() { 
    var self = this; 

    // get the semantic data for this subject 
    // setup the handler function 
    var functionName = "subjectHandler" + new Date().getTime(); 
    window[functionName] = function(data) { 
    // invoke function with saved context and parameter  
    self._fillFromSP.call(self, data);  
    } 
    window[functionName](json); 
}; 

var json = {"doc":{"info" ... "length":48}]}}; 

其中JSON變量從同樣的semanticproxy網址之前保存的數據。所有相關節點都呈現並呈現得非常漂亮。所以只有當我使用$ .ajax調用時,只有當數據實際返回到我的瀏覽器時才鎖定。我可以遍歷代碼,並使用正確的參數調用$('body')。triggerHandler正確的次數。它成功地觸發了Explorer.addEdge()調用的所有內容,其中要求樹幹粒子系統添加一些節點 - 並且這種情況不起作用。但只有在使用AJAX調用時!

任何想法?提前致謝。

更新: 我只設置了一個小的Rails控制器作爲代理使用。沒有運氣。相反,$就調用和怪異的窗口句柄,在填入方法我只是做了一個直:

var url = "http://localhost:3000/?url=http://service.semanticproxy.com/processurl/8bv73k5hgj9prkhee9rrr9s4/json/http://en.wikipedia.org/wiki/Andreas_Michl"; 
$.getJSON(url, function(data) { 
    self._fillFromSP(data); 
}); 

但是,有同樣的行爲 - 鎖定。也許是一個競爭條件或其他在喬木代碼?

解決方案

populate方法,現在讀取:

// fills this node with data from Wikipedia and SemanticProxy 
Node.prototype.populate = function() { 
    var self = this; 

    // get the semantic data for this subject 
    var ajaxWorker = new Worker('javascripts/worker_ajax.js'); 
    ajaxWorker.onmessage = function(event) {  
    self._fillFromSP(event.data); 
    }; 
    ajaxWorker.postMessage({name: this.name}); 
}; 

和worker_ajax.js是:

onmessage = function(event) { 
    var SP_KEY = "xxxx"; 
    var url = "http://service.semanticproxy.com/processurl/"+SP_KEY+"/jsonp:handle/http://en.wikipedia.org/wiki/"+event.data.name; 
    importScripts(url); 
} 

var handle = function(json) { 
    postMessage(json); 
} 

回答

1

WebWorkers和JSONP不走在一起,因爲WebWorkers沒有DOM將元素附加到,換句話說,您不能將腳本標記附加到任何位置。

閱讀這篇文章,爲可能的解決方法:http://cggallant.blogspot.com/2010/10/jsonp-overview-and-jsonp-in-html-5-web.html

至於在Webworkers使用JQuery,看看這個話題:HTML Web Worker and Jquery Ajax call

+0

嗨Peeter,對於信息的感謝。不幸的是我仍然不清楚。我的腳本沒有在web worker中運行,所以我認爲它可以創建AJAX調用,然後將nodeName傳遞到arbor以將其插入物理系統,這是駐留在worker中的唯一東西。實際上,即使我在kernel.js中關閉了worker的使用 - var USE_WORKER = false - 它仍然失敗。 – kmc 2011-04-13 00:10:01

+0

啊,明白了!詳情請參閱原文。 – kmc 2011-04-15 06:06:56

相關問題