2012-11-28 27 views
21

मैं जानना चाहता हूं कि Sankey diagram example को संशोधित करने का कोई आसान तरीका है ताकि नए डेटा में चिकनी संक्रमण हो। उदाहरण के लिए, कल्पना करें कि मेरे पास अलग-अलग डेटाफाइल हैं (energy1.json, energy2.json ...) पहले डेटासेट के लिए एक सांकी आरेख को डी 3 प्लॉट कैसे कर सकता है, फिर इंतजार कर रहा है और बाद में दूसरे डेटासेट का प्रतिनिधित्व करने के लिए बॉक्स स्वभाव को पुन: व्यवस्थित करता है?संकी आरेख संक्रमण

+0

आप कभी भी इस समाधान हो गया? – PhoebeB

+1

क्या आपके सभी डेटाफाइलों में एक ही नोड्स होंगे लेकिन उनके बीच अलग-अलग प्रवाह होगा? – ASGM

उत्तर

14

यह संभव है। एक सीएसवी फ़ाइल का उपयोग कर एक दृष्टिकोण यहाँ है। Sankey यहाँ कार्य करना: https://www.betterment.com/resources/investment-strategy/portfolio-management/portfolio-diversification/

  1. अपने d3.csv कॉल के बाहर एक वैश्विक सरणी को परिभाषित करें।

    var portfolioValues = []; 
    
  2. है, नोड/लिंक संरचना बनाने के अपने वैश्विक सरणी मूल्यों पुश करने के लिए सीएसवी को पार्स।

    d3.csv("etf-geo.csv", function(error, data) { 
        graph = {"nodes" : [], "links" : []}; 
        data.forEach(function (d, i) { 
         var item = { source: d.source, target: d.target, values: [] }; 
         for (var j=0; j < 101; j++) { 
          item.values.push(d['value'+j.toString()]); 
         } 
         portfolioValues.push(item); 
         graph.nodes.push({ "name": d.source }); 
         graph.nodes.push({ "name": d.target }); 
         graph.links.push({ 
          source: portfolioValues[i].source, 
          target: portfolioValues[i].target, 
          value: portfolioValues[i].values[startingAllocation] 
         }); 
        }); 
    
    //this handy little function returns only the distinct/unique nodes 
    graph.nodes = d3.keys(
        d3.nest() 
         .key(function (d) { return d.name; }) 
         .map(graph.nodes) 
    ); 
    
    // it appears d3 with force layout wants a numeric source and target 
    // so loop through each link replacing the text with its index from node 
    graph.links.forEach(function (d, i) { 
        graph.links[i].source = graph.nodes.indexOf(graph.links[i].source); 
        graph.links[i].target = graph.nodes.indexOf(graph.links[i].target); 
        portfolioValues[i].source = graph.links[i].source; 
        portfolioValues[i].target = graph.links[i].target; 
    }); 
    
    // now loop through each nodes to make nodes an array of objects 
    // rather than an array of strings 
    graph.nodes.forEach(function (d, i) { 
        graph.nodes[i] = { "name": d }; 
    }); 
    
    // construct sankey 
    sankey 
        .nodes(graph.nodes) 
        .links(graph.links) 
        .layout(); 
    
  3. एक बदलाव के लिए सुनो और अपने अद्यतन कार्य करने के लिए उपयोगकर्ता इनपुट गुजरती हैं।

    $(".sankey-slider").bind("slider:changed", function (event, data) { 
    
    slideValue = data.value; 
    
    updateData(parseInt(slideValue)); 
    
    }); 
    
  4. एक अस्थायी सरणी बनाएँ और वैश्विक सरणी से सही मान पुनः प्राप्त। लेआउट को फिर से समझने के लिए sankey कार्यों को बुलाओ।

    var newLinks = []; 
    
        portfolioValues.forEach(function(p, i) { 
         newLinks.push({ 
          source: p.source, 
          target: p.target, 
          value: p.values[allocation] 
         }); 
        }); 
    
        graph.links = newLinks; 
    
        sankey 
        .nodes(graph.nodes) 
        .links(graph.links) 
        .size([width, height]) 
        .layout(); 
    
  5. प्रत्येक तत्व है कि बदलने की आवश्यकता का चयन करें और नया डेटा मान गुजरती हैं।

    d3.selectAll(".link") 
        .data(graph.links) 
        .attr("d", path) 
        .attr("id", function(d,i){ 
        d.id = i; 
        return "link-"+i; 
        }) 
        .style("stroke-width", function(d) { return Math.max(1, d.dy); }) 
        .sort(function(a, b) { return b.dy - a.dy; }); 
    
    d3.selectAll(".node").attr("transform", function(d) { 
        return "translate(" + d.x + "," + d.y + ")"; }); 
    
    d3.selectAll("rect") 
    .attr("height", function(d) { return d.dy; }) 
    .on("mouseover",highlight_node_links) 
    .on("mouseout",onNodeMouseout); 
    

यहाँ Sankey कार्य करना: https://www.betterment.com/resources/investment-strategy/portfolio-management/portfolio-diversification/

+0

हाय @ जो-जेन्सन आपके कोड के साथ एक jsfiddle है। यह आवश्यकतानुसार कांटा और चिमटा करने के लिए एक पर्यावरण के लिए बेहद उपयोगी होगा। – lwall

2

के बाद से नोड्स के स्वत: स्थिति एक हिस्सा है जो एक जुड़ा ग्राफ जो एक एनपी अनुकूलन समस्या है में लिंक दूरी को कम करने की कोशिश करता भी शामिल है, अनुकूलक के किसी भी प्रकार संभवतः एक और लेआउट में एक कूद करने के लिए अग्रणी करने के लिए एक न्यूनतम से कूद कर सकते हैं। तो एक गारंटीकृत चिकनी संक्रमण संभव नहीं होगा।

निकटतम संभावित समाधान शायद दो इनपुट डेटा सेटों के बीच रैखिक रूप से इंटरपोलेट करना होगा और इस प्रकार ग्राफ की एक श्रृंखला उत्पन्न होगी (डेटा के आधार पर) एक या दूसरे से कम या आसानी से संक्रमण।

उम्मीद है कि इससे मदद मिलती है।

+0

क्या आप jsfiddle पर एक उदाहरण जोड़ सकते हैं? वह बहुत उपयोगी होगा! – lwall