12

Quiero dibujar un Sankey diagram usando Javascript. ¿Alguien puede proporcionar alguna dirección con respecto a los algoritmos o las bibliotecas que están disponibles para esto?Diagrama de Sankey en javascript

+0

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

Respuesta

11

Este es un diagrama de Sankey básica usando 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; 
    } 
} 

y lo uso como esto:

<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

Enlace actualizado: https://dmitrybaranovskiy.github.io/raphael/ – u01jmg3

1

Gracias a zenify para mí comenzar en el camino, tuve que reajustar algunas de las copió el código anterior para que funcione, pero definitivamente da un buen punto de partida. El siguiente código se puede copiar en un archivo .htm y solo necesita tener raphael-min.js en el mismo directorio para que funcione.

Saludos/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

¡Eso es genial! ¿Ahora tiene alguna idea sobre cómo los diagramas creados pueden exportarse a un formato de imagen que pueda guardar el usuario? – 321zeno

+0

Hmm, eso está más allá de mí por el momento. Por el momento estoy pensando en la idea de un plugin jquery que actúe sobre una tabla html de datos donde ingresas la ID de la tabla, la columna de datos y la columna del título al plugin. El sueño es que genera el sankey y también extiende la tabla para permitirle reordenar dinámicamente los diferentes valores, establecer el ángulo/longitud de la flecha y un millón de otras cosas. –

Cuestiones relacionadas