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
risposta
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>
Link aggiornato: https://dmitrybaranovskiy.github.io/raphael/ – u01jmg3
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>
È grandioso! Ora hai qualche idea su come i diagrammi creati potrebbero essere esportati in un formato immagine che potrebbe essere salvato dall'utente? – 321zeno
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. –
In caso di aiuto agli altri: ho estratto il mio codice javascript disegno diagramma di Sankey qui:
http://tamc.github.com/Sankey/
L'utilizzo originale è sul sito del governo britannico :
D3.js utilizza un plugin per creare diagrammi di sankey piuttosto bene.
Ecco una spiegazione piuttosto dettagliata di come funziona il codice Sankey diagramma D3 a base di Mike Bostock: http://www.d3noob.org/2013/02/sankey-diagrams-description-of-d3js-code.html
Ho implementato questo su un application server Grails-based e funziona.
Google Charts include il diagramma Sankey: https://developers.google.com/chart/interactive/docs/gallery/sankey
questione connessa: http://stats.stackexchange.com/questions/24074/whats-a-good-tool-to-create-sankey-diagrams/24114# 24114 – Thilo