2011-09-13 20 views

Respuesta

9

I logró salvar el gráfico simplemente por tener todos los elementos dentro de una matriz de objetos, donde cada objeto tiene fuente y nodos de destino, coordenadas X, Y.

Al guardar, simplemente haga JSON.stringify(whole_object), y si está cargando, simplemente JSON.parse() y coloque manualmente los nodos y conéctelos.

+0

¿puede compartir algún código? Estoy confundido acerca de cómo cargarlos y conectarlos. –

+0

Oh ... Fue hace mucho tiempo, pero por lo que recuerdo simplemente guarde los datos por JSON.stringify (objectCollection). Hay relaciones, posiciones, etc. Ahora, cuando quieras cargar, haz JSON.parse (generatedStrnig) y luego pasa manualmente por cada nodo en el objeto y colócalo (con CSS) y conéctalos (con jsPlumb API). Lo siento, no recuerdo exactamente :) –

0

Estoy usando YUI con él. Estoy guardando la posición de cada elemento del cuadro que está conectado en una tabla. Si tienen una tabla separada, almacena una relación de padre a hijo entre los elementos, que se usa para determinar las líneas que jsPlumb debe dibujar. Lo determino usando un proceso de selección en el que el primer elemento seleccionado es el padre y todos los demás elementos son hijos. Cuando se hace clic en el botón "conectar", se borra la selección principal/secundaria de los elementos. También alternar esto si hace clic en el elemento primario seleccionado; también borra las selecciones secundarias.

2

Hace poco escribí esta entrada del blog acerca de por qué jsPlumb no tiene una función de guardar (y lo que te recomiendo que hagas):

http://jsplumb.tumblr.com/post/11297005239/why-doesnt-jsplumb-offer-a-save-function

... tal vez alguien que le resulte útil.

+6

Lo que la gente está buscando es una manera simple de decir: persista este diagrama en xml/json, o guárdelo de alguna otra forma que pueda analizarse fácilmente y mapeado para actualizar el modelo de datos ... Parece que es una cosa obvia de usabilidad. Parece que lo que describiste aquí hará que tome muchos pasos extra molestos para llegar allí de la manera que quiero llegar allí. –

+0

El enlace ha muerto ... –

7

Mi solución guardar y cargar jsPlumb:

function Save() { 
    $(".node").resizable("destroy"); 
    Objs = []; 
    $('.node').each(function() { 
     Objs.push({id:$(this).attr('id'), html:$(this).html(),left:$(this).css('left'),top:$(this).css('top'),width:$(this).css('width'),height:$(this).css('height')}); 
    }); 
    console.log(Objs); 
} 


function Load() { 
    var s=""; 
    for(var i in Objs) { 
     var o = Objs[i]; 
     console.log(o); 
     s+='<div id="'+ o.id+'" class="node" style="left:'+ o.left+'; top:'+ o.top+'; width:'+ o.width +'; height:'+ o.height +' "> '+ o.html+'</div>'; 
    } 
    $('#main').html(s); 
} 

UPD Demostración: http://jsfiddle.net/Rra6Y/137/

Nota: si Demo no funciona en jsFiddle, asegúrese de que apunta a un enlace jsPlumb existente (enlaces se enumeran en "Recursos externos", elemento del menú JsFiddle

+0

Hola y gracias por estas sugerencias. Solo trato de crear un diseñador de máquina de estado finito en línea con jsplumb y para guardar/cargar correctamente, necesito pasar más datos que el html que agregaste a mi matriz. Algo así como "nombre de estado", "conectado a", etc. Ya sabes, algo para guardar realmente mi "máquina de estados", no solo mi "dibujo". ¿Tiene una pista sobre cómo hacer esto, tal vez? ¡sería genial! – Dominik

+0

el enlace jsfiddle no funciona. No se puede arrastrar y no se crean conexiones. Hay errores en la consola para guardar, cargar y borrar. –

3

Mi función de guardar hace algo más que guardar la posición x, y del elemento y sus conexiones. También agregué guardar una superposición de etiquetas de conexión, así como texto personalizado para cada elemento. yo u puede adaptar esta solución según sus necesidades, pero aquí es básicamente:

//save functionality 
    function IterateDrawnElements(){ //part of save 
     var dict = {}; 
     $('#id_diagram_container').children('div.window').each(function() { 
      var pos = $(this).position() 
      var diagram_label = $(this).children('div.asset-label').children('div.asset-diagram-label').text() 
      if (diagram_label == null || diagram_label == ''){ 
       diagram_label=''; 
      } 
      dict[this.id] = [pos.left, pos.top, diagram_label]; 
     }); 
     return dict; 
    } 
    function IterateConnections(){ //part of save 
     var list = []; 
     var conns = jsPlumb.getConnections() 
     for (var i = 0; i < conns.length; i++) { 
      var source = conns[i].source.id; 
      var target = conns[i].target.id; 
      try{ 
       var label = conns[i].getOverlay("label-overlay").labelText; 
      } 
      catch(err) { 
       label = null 
      } 
      //list.push([source, target]) 
      if (source != null && target != null){ 
       list.push([source, target, label]); 
      }; 
     } 
     return list; 
    } 

que inicio todo esto cuando el usuario pulsa el botón de guardar, una llamada AJAX se hace de nuevo al servidor, en este caso Django está interceptando la solicitud ajax y guarda los datos en la base de datos.

// ajax llamada cuando pulsa el botón Guardar $ save_btn.click (function() {

//drawn elements 
var d_elements = IterateDrawnElements(); 
var d_conns = IterateConnections(); 
var d_name =$('#id_diagram_name').val(); 

$.ajax({ 
    url : ".", 
    type : "POST", 
    dataType: "json", 
    data : { 
     drawn_elements: JSON.stringify(d_elements), 
     conns: JSON.stringify(d_conns), 
     diagram_name: d_name, 
     csrfmiddlewaretoken: '{{ csrf_token }}' 
    }, 
    success: function (result) { 

     if (result.success == true){ 
      save_status.html(result.message) 
     } 
     //console.log(JSON.stringify(result)); 
     $save_btn.attr('disabled','disabled'); 
     if (result.old_name != false){ 
      //alert() 
      $('#id_diagram_name').val(result.old_name) 
     } 
    }, 
    error: function(xhr, textStatus, errorThrown) { 
     alert("Please report this error: "+errorThrown+xhr.status+xhr.responseText); 
    } 
}); 
//return false; // always return error? 

});

Cargar todo esto es aún más fácil y hay muchas formas de hacerlo. En Django puedes simplemente generar el html directamente en tu plantilla así como el js para las conexiones o puedes crear un objeto JSON en javascript para todo y luego tener javascript dibujarlo todo basado en la matriz. Usé jquery para esto.

//js & connections load 

var asset_conns = [ 
    {% for conn in diagram_conns %} 
    [ {{ conn.source.id }}, {{ conn.target.id }}, '{{ conn.name }}' ], 
    {% endfor %} 
] 


// Takes loaded connections and connects them 
for (var i = 0; i< asset_conns.length; i++){ 
    var source = asset_conns[i][0].toString(); 
    var target = asset_conns[i][1].toString(); 
    var label = asset_conns[i][2]; 
    var c = jsPlumb.connect({source: source, target: target, detachable:true, reattach: true }); //on init already know what kind of anchor to use! 
    if (label != null && label != 'None'){ 
     c.addOverlay([ "Label", { label: label, id:"label-overlay"} ]); 
    } 
} 

//html right into django template to draw elements, asset element interchangeable terms 

{% for element in drawn_elements %} 
    <div id="{{ element.asset.id }}" class="window" style="left:{{ element.left }}px;top:{{ element.top }}px;background-image: url('{% static element.asset.asset_mold.image.url %}'); width: {{ element.asset.asset_mold.image.width }}px;height: {{ element.asset.asset_mold.image.height }}px;"> 
     <div class="asset-label" id="label-{{ element.asset.id }}"> 
      {#{{ element.asset }}#}<a class="lbl-link" id="lbl-link-{{ element.asset.id }}" href="{{ element.asset.get_absolute_url }}">{{ element.asset }}</a> 
      <div class='asset-diagram-label' id="lbl-{{ element.asset.id }}">{% if element.asset.diagram_label %}{{ element.asset.diagram_label }}{% endif %}</div> 
     </div> 
     <div class='ep' id="ep-{{ element.asset.id }}"></div> 
    </div> 
{% endfor %} 

Se puede simplificar en gran medida esta pero la mía también obtiene un fondo para el elemento, así como la etiqueta y la forma del elemento a utilizar con anclajes perimetrales. Esta solución funciona y está probada. Pronto lanzaré una aplicación de código abierto de Djago en PyPi.

Cuestiones relacionadas