12

Desidero disegnare un Sankey diagram utilizzando Javascript. Qualcuno può fornire alcune indicazioni sugli algoritmi o le librerie disponibili per questo?Diagramma di Sankey in javascript

+0

questione connessa: http://stats.stackexchange.com/questions/24074/whats-a-good-tool-to-create-sankey-diagrams/24114# 24114 – Thilo

risposta

11

Questo è uno schema di base Sankey utilizzando raphaeljs

function Sankey(x0, y0, height, losses) { 
    var initialcolor = Raphael.getColor(); 
    var start = x0 + 200; 
    var level = y0 + height; 
    var heightunit = height/100; 
    var remaining = 100 * heightunit; 

    function drawloss(start, level, loss) { 
     var thecolor = Raphael.getColor(); 
     paper.path("M" + (start - 100) + "," + (level - loss) + "L" + start + "," + (level - loss)).attr({stroke: thecolor}); 
     paper.path("M" + (start - 100) + "," + level + "L" + start + "," + level).attr({stroke: thecolor}); 
     paper.path("M " + start + "," + level + " Q" + (start + 100) + "," + level + " " + (start + 100) + "," + (level + 100)).attr({stroke: thecolor}); 
     paper.path("M " + start + "," + (level - loss) + " Q" + (start + 100 + loss) + "," + (level - loss) + " " + (start + 100 + loss) + "," + (level + 100)).attr({stroke: thecolor}); 
     paper.path("M " + (start + 100) + "," + (level + 100) + " L " + (start - 10 + 100) + "," + (level + 100) + " L " + (start + loss/2 + 100) + "," + (level + 110) + " L " + (start + loss + 10 + 100) + "," + (level + 100) + " L " + (start + loss + 100) + ", " + (level + 100)).attr({stroke: thecolor}); 
    } 

    function drawremaining(start, level, loss) { 
     paper.path("M 100," + y0 + "L" + (start + 100) + "," + y0).attr({stroke: initialcolor}); 
     paper.path("M" + (start - 100) + "," + level + "L" + (start + 100) + "," + level).attr({stroke: initialcolor}); 
     paper.path("M " + (start + 100) + " " + y0 + " L " + (start + 100) + " " + (y0 - 10) + " L " + (start + 110) + " " + (y0 + loss/2) + " L " + (start + 100) + " " + (level + 10) + " L " + (start + 100) + " " + level).attr({stroke: initialcolor}); 
    } 

    function drawstart(x0, y0, width, height) { 
     paper.path("M " + x0 + "," + y0 + "L" + (x0 + width) + "," + y0).attr({stroke: initialcolor}); 
     paper.path("M " + x0 + "," + (y0 + height) + "L" + (x0 + width) + "," + y0 + height)).attr({stroke: initialcolor}); 
     paper.path("M " + x0 + "," + y0 + "L" + x0 + "," + (y0 + height)).attr({stroke: initialcolor}); 
    } 

    drawstart(x0, y0, 100, height); 

    for (var i in losses) { 
     drawloss(start, level, losses[i] * heightunit); 
     remaining -= losses[i] * heightunit; 
     level -= losses[i] * heightunit; 
     start += 100; 
    } 
} 

e lo uso come questo:

<div id="notepad" style="height:1000px; width:1000px; background: #eee"></div> 
<script type="text/javascript"> 
    var paper = Raphael(document.getElementById("notepad"), 1020, 1000); 
    var losses=[50, 30, 5]; 
    Sankey(10, 100, 200, losses); 
</script> 
+1

Link aggiornato: https://dmitrybaranovskiy.github.io/raphael/ – u01jmg3

1

Grazie a zenify per me iniziare sulla strada, ho avuto di adeguare alcuni dei copiato il codice sopra per farlo funzionare ma sicuramente dà un buon punto di partenza. Il seguente codice può essere copiato in un file .htm e devi solo avere raphael-min.js nella stessa directory per farlo funzionare.

Regards/Colm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" class="JS"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
<title>Raphael makes Sankey</title> 
<script type="text/javascript" src="raphael-min.js"></script> 
<script type="text/javascript"> 
function Sankey(x0,y0,height,losses){ 
    initialcolor= Raphael.getColor(); 
    var start=x0+200; 
    var level=y0+height;  
    var heightunit=height/100; 
    var remaining=100*heightunit; 

function drawloss(start,level,loss){ 
    var thecolor=Raphael.getColor(); 
    paper.path("M"+(start-100)+","+(level-loss)+"L"+start+","+(level-loss)).attr({stroke: thecolor}); 
    paper.path("M"+(start-100)+","+(level)+"L"+start+","+(level)).attr({stroke: thecolor}); 
    paper.path("M "+start+","+level+" Q"+(start+100)+","+level+" "+(start+100)+","+(level+100)).attr({stroke: thecolor}); 
    paper.path("M "+start+","+(level-loss)+" Q"+(start+100+loss)+","+(level-loss)+" "+(start+100+loss)+","+(level+100)).attr({stroke: thecolor}); 
    paper.path("M "+(start+100)+","+(level+100)+" L "+(start-10+100)+","+(level+100)+" L "+(start+(loss/2)+100)+","+(level+110)+" L "+(start+(loss)+10+100)+","+(level+100)+" L "+(start+(loss)+100)+", "+(level+100)).attr({stroke: thecolor}); 
} 

function drawremaining(start,level,loss){ 
    paper.path("M 100,"+y0+"L"+(start+100)+","+y0).attr({stroke: initialcolor}); 
    paper.path("M"+(start-100)+","+(level)+"L"+(start+100)+","+(level)).attr({stroke: initialcolor}); 
    paper.path("M "+(start+100)+" "+y0+" L "+(start+100)+" "+(y0-10)+" L "+(start+110)+" "+(y0+(loss/2))+" L "+(start+100)+" "+(level+10)+" L "+(start+100)+" "+(level)).attr({stroke: initialcolor}); 
} 

function drawstart(x0, y0, width, height){ 
    paper.path("M "+x0+","+y0+"L"+(x0+width)+","+y0+"").attr({stroke: initialcolor}); 
    paper.path("M "+x0+","+(y0+height)+"L"+(x0+width)+","+y0+height+"").attr({stroke: initialcolor}); 
    paper.path("M "+x0+","+y0+"L"+x0+","+(y0+height)+"").attr({stroke: initialcolor}); 
} 

    drawstart(x0,y0,100,height); 
    for (var i in losses){ 
     drawloss(start,level,losses[i]*heightunit); 
     remaining-=losses[i]*heightunit; 
     level-=losses[i]*heightunit; 
     start+=100; 
    } 
    drawremaining(start, level, remaining); 
} 
</script> 
</head> 
<body id="blog"> 
    <div id="notepad" style="height:1000px; width:1000px; background: #eee"></div> 
    <script type="text/javascript"> 
    var paper = Raphael(document.getElementById("notepad"), 1020, 1000); 
    var losses=[50, 30, 5]; 
    Sankey(10, 100, 200, losses); 
    </script> 
</body> 
</html> 
+0

È grandioso! Ora hai qualche idea su come i diagrammi creati potrebbero essere esportati in un formato immagine che potrebbe essere salvato dall'utente? – 321zeno

+0

Hmm, questo è oltre me per il momento. Al momento sto pensando all'idea di un plugin jQuery che agisca su una tabella HTML di dati in cui inserisci l'id della tabella, la colonna di dati e la colonna del titolo nel plugin. Il sogno è che genera il sankey e estende anche la tabella per consentire di riordinare in modo dinamico i diversi valori, impostare l'angolo/lunghezza della freccia e un milione di altre cose. –

Problemi correlati