JQuery

2011-03-13 6 views
5

के माध्यम से गतिशील रूप से लोड किए गए डेटा के साथ प्रोटोविस का उपयोग करना मैं गतिशील रूप से कुछ सामाजिक नेटवर्क डेटा को एक वेब पेज में लोड कर रहा हूं जिसे मैं प्रोटॉविस का उपयोग करके देखना चाहता हूं। (वास्तव में, डेटा को दो पास प्रक्रिया में लोड किया जाता है - पहले उपयोगकर्ता की एक सूची ट्विटर से नाम पकड़े गए हैं, फिर Google सोशल एपीआई से सोशल कनेक्शन की एक सूची पकड़ी गई है।) प्रोटॉविस कोड एक इवेंट लूप के अंदर चल रहा है, जिसका मतलब है कि डाटा लोडिंग कोड को इस लूप के बाहर होना चाहिए।JQuery

प्रोटॉविस इवेंट लूप "स्विचिंग" करने से पहले, मैं पृष्ठ में डेटा कैसे लोड करूं और इसे पार्स कैसे करूं? फिलहाल, मुझे लगता है कि एक दौड़ की स्थिति है जिसके द्वारा प्रोटोविस नेटवर्क डेटा को विज़ुअलाइज़ करने का प्रयास करता है जिसे अभी तक लोड नहीं किया गया है और अभी तक पार्स नहीं किया गया है?

<html><head><title></title> 

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script> 
<script type="text/javascript" src="../protovis-3.2/protovis-r3.2.js"></script> 
<script type="text/javascript"> 

//getNet is where we get a list of Twitter usernames 
function getNet(){ 

    url="http://search.twitter.com/search.json?q=jisc11&callback=?" 
    $.getJSON(url,function(json){ 
    users=[] 
    uniqusers={} 
    for (var u in json['results']) { 
     uniqusers[json['results'][u]['from_user']]=1 
    } 
    for (var uu in uniqusers) 
     users.push(uu) 
    getConnections(users) 
    }) 
} 

//getConnections is where we find the connections between the users identified by the list of Twitter usernames 
function getConnections(users){ 
    //Google social API limits lookup to 50 URLs; need to page this... 
    if (users.length>50) 
    users=users.slice(0,49) 
    str='' 
    for (var uic=0; uic<users.length; uic++) 
    str+='http://twitter.com/'+users[uic]+',' 
    url='http://socialgraph.apis.google.com/lookup?q='+str+'&edo=1&callback=?'; 

    $.getJSON(url,function(json){ 
    graph={} 
    graph['nodes']=[] 
    userLoc={} 

    for (var uic=0; uic<users.length; uic++){ 
     graph['nodes'].push({nodeName:users[uic]}) 
     userLoc[users[uic]]=uic 
    } 

    graph['links']=[] 
    for (u in json['nodes']) { 
     name=u.replace('http://twitter.com/','') 
     for (var i in json['nodes'][u]['nodes_referenced']){ 
     si=i.replace('http://twitter.com/','') 
     if (si in userLoc){ 
      if (json['nodes'][u]['nodes_referenced'][i]['types'][0]=='contact') 
      graph['links'].push({source:userLoc[name], target:userLoc[si]}) 
     } 
     } 
    } 

    followers={} 
    followers={nodes:graph['nodes'],links:graph['links']} 
    }); 
} 

$(document).ready(function() { 
    users=['psychemedia','mweller','mhawksey','garethm','gconole','ambrouk'] 
    //getConnections(users) 
    getNet() 
}) 

</script> 
</head> 

<body> 
<div id="center"><div id="fig"> 
    <script type="text/javascript+protovis"> 
     // This code is taken directly from the protovis example 
     var w = document.body.clientWidth, 
     h = document.body.clientHeight, 
     colors = pv.Colors.category19(); 

     var vis = new pv.Panel() 
     .width(w) 
     .height(h) 
     .fillStyle("white") 
     .event("mousedown", pv.Behavior.pan()) 
     .event("mousewheel", pv.Behavior.zoom()); 

     var force = vis.add(pv.Layout.Force) 
     .nodes(followers.nodes) 
     .links(followers.links); 

     force.link.add(pv.Line); 

     force.node.add(pv.Dot) 
     .size(function(d) (d.linkDegree + 4) * Math.pow(this.scale, -1.5)) 
     .fillStyle(function(d) d.fix ? "brown" : colors(d.group)) 
     .strokeStyle(function() this.fillStyle().darker()) 
     .lineWidth(1) 
     .title(function(d) d.nodeName) 
     .event("mousedown", pv.Behavior.drag()) 
     .event("drag", force) 
     //comment out the next line to remove labels 
     //.anchor("center").add(pv.Label).textAlign("center").text(function(n) n.nodeName) 

     vis.render(); 

    </script> 
    </div></div> 

</body></html> 
+0

क्या मेरा अद्यतन उत्तर अब आपकी समस्या का समाधान करता है? –

+0

मैंने ट्विटर और Google सोशल एपीआई के लिए जेम्स क्रूक के समाधान डब्ल्यू/JQuery बनाने के प्रश्नों का उपयोग करके एक डेमो ब्लॉग किया है, फिर परिणाम ग्राफिंग: blog.ouseful.info/2011/04/12/using-protovis-to-visualise-connections- बीच-लोग-ट्वीटिंग-ए-स्पेशल-टर्म/ – psychemedia

उत्तर

5

vis.render() वर्तमान में डेटा प्राप्त करने से पहले आपको कॉल किया जा रहा है। अन्य मुद्दे भी हो सकते हैं, लेकिन इसे getNet() के बाद होना चाहिए।


संपादित करें 1:

vis.render() अब getNet() के बाद है। मैंने प्रोटोकिस फोर्स लेआउट सृजन कोड को फ़ंक्शन के अंदर रखा है ताकि जब इसे निष्पादित किया जा सके, मैं इसे नियंत्रित कर सकूं, और vis और followers प्रारंभिक कोड और createLayout कोड दोनों के लिए दृश्यमान चर बना दिया।

प्रोटोविस, विशेष रूप से बल लेआउट, त्रुटियों के बारे में बहुत क्षमा नहीं कर रहा है - उदा। गलत संरचना या नोड्स/लिंक डेटास्ट्रक्चर के लिए तत्वों की गिनती, और यह नहीं बताती कि क्या हो रहा है, इसलिए विकासशील में सबसे पहले स्थिर डेटा का उपयोग करना सबसे अच्छा है जिसे आप जानते हैं कि सही प्रकार का है, और उसके बाद बाद में गतिशील रूप से बनाए गए डेटा के साथ प्रतिस्थापित करें ।

आपके पास होने वाली समस्या का एक हिस्सा यह है कि type="text/javascript+protovis" का उपयोग प्रोटोविस द्वारा जावास्क्रिप्ट पुनर्लेखन को आमंत्रित करता है। नीचे दिया गया कोड type="text/javascript" का उपयोग करता है और इसमें अतिरिक्त {} एस और return है जो +protovis सहेजता है। यह getJSON() और क्रोम ब्राउज़र में coexist करने के लिए protovis, getNet() बार-बार कहा जाता है।

<html><head><title></title> 

<script type="text/javascript" src="jquery.js"></script> 
<script type="text/javascript" src="protovis-d3.2.js"></script> 

<body> 
<div id="center"><div id="fig"> 

<script type="text/javascript"> 
var vis; 
var followers={}; 

function createLayout(){ 
    var w = document.body.clientWidth, 
    h = document.body.clientHeight, 
    colors = pv.Colors.category19(); 

    vis = new pv.Panel() 
     .width(w) 
     .height(h) 
     .fillStyle("white") 
     .event("mousedown", pv.Behavior.pan()) 
     .event("mousewheel", pv.Behavior.zoom()); 

    var force = vis.add(pv.Layout.Force) 
     .nodes(followers.nodes) 
     .links(followers.links); 

    force.link.add(pv.Line); 
    force.node.add(pv.Dot) 
     .size(function(d){ return (d.linkDegree + 4) * Math.pow(this.scale, -1.5);}) 
     .fillStyle(function(d){ return d.fix ? "brown" : colors(d.group);}) 
     .strokeStyle(function(){ return this.fillStyle().darker();}) 
     .lineWidth(1) 
     .title(function(d){return d.nodeName;}) 
     .event("mousedown", pv.Behavior.drag()) 
     .event("drag", force); 
     //comment out the next line to remove labels 
     //.anchor("center").add(pv.Label).textAlign("center").text(function(n) n.nodeName) 
    vis.render(); 
} 

function getNet(){ 
    // OK to have a getJSON function here. 

    followers={nodes:[{nodeName:'mweller', group:6}, 
    {nodeName:'mhawksey', group:6}, 
    {nodeName:'garethm', group:6}, 
    {nodeName:'gconole', group:6}, 
    {nodeName:'ambrouk', group:6} 
    ], 
    links:[ 
    {source:0, target:1, value:1}, 
    {source:1, target:2, value:1}, 
    {source:1, target:4, value:1}, 
    {source:2, target:3, value:1}, 
    {source:2, target:4, value:1}, 
    {source:3, target:4, value:1}]}; 
} 

$(document).ready(function() { 
    getNet(); 
    createLayout(); 
}) 
</script> 

</head> 

</div></div> 

</body></html> 

संपादित करें 2:

मामले में आप थोड़ा गहराई में रुचि रखते हैं, समस्या protovis में इस कोड से आता है:

pv.listen(window, "load", function() { 
    pv.$ = {i:0, x:document.getElementsByTagName("script")}; 
    for (; pv.$.i < pv.$.x.length; pv.$.i++) { 
    pv.$.s = pv.$.x[pv.$.i]; 
    if (pv.$.s.type == "text/javascript+protovis") { 
     try { 
     window.eval(pv.parse(pv.$.s.text)); 
     } catch (e) { 
     pv.error(e); 
     } 
    } 
    } 
    delete pv.$; 
}); 

तकनीक मैं करने के लिए उपयोग किया है "text/javascript" का उपयोग करें और "text/javascript+protovis" का उपयोग करने से बचें, दोनों आपकी समस्या हल करते हैं और फ़ायरफ़ॉक्स में प्रोटोविस का उपयोग करके कोड डीबग करना आसान बनाता है।

+0

हां - और मैं नहीं देख सकता कि vis.render() को कॉल कैसे करें जब मैं टाइप = "टेक्स्ट/जावास्क्रिप्ट" कोड से टाइप = "टेक्स्ट/जावास्क्रिप्ट + protovis "कोड? – psychemedia

+0

उस अतिरिक्त संपादन के लिए धन्यवाद; समस्या जो मैं कर रहा था - और अभी भी मिलता है - यह है कि अगर मैं $ .getJSON को getNet() फ़ंक्शन में कॉल करता हूं, तो ऐसा लगता है कि इसे बार-बार कहा जाता है (क्रोम, ओएस/एक्स 10.5.8)? मेरी धारणा यह थी कि प्रोटॉविस एनीमेशन चलने के लिए एक इवेंट लूप चल रहा है, और किसी भी तरह से उस लूप संदर्भ में getJSON कॉल को बुलाया जा रहा है? – psychemedia

+0

क्रोम ब्राउज़र में जावास्क्रिप्ट पुनर्लेखन से बचने के लिए अद्यतन उदाहरण। –

0

ग्रेट जॉब जेम्स - केवल एक चीज देखने के लिए: यदि आप createLayout() रखते हैं; jQuery $(document).ready() फ़ंक्शन के भीतर कॉल करें, आपको लगता है कि आपका पैनल गलत जगह पर दिखाई दे रहा है ... यदि आप पैनल को अपनी स्क्रिप्ट में div के भीतर दिखाना चाहते हैं, तो jQuery रेफरी को हटा दें और सभी ठीक होना चाहिए।

संपादित करें: मैं बार मैं यह लिखा पर Protovis में कैनवास पैरामीटर के बारे में पता नहीं था - बस पैनल के लिए कैनवास divid जोड़ने, प्लस कि आईडी के साथ एक div, स्थिति मुद्दों का ख्याल पूरी तरह से लेता है।