2011-09-13 11 views

risposta

9

sono riuscito a salvare il grafico semplicemente avendo tutti gli elementi all'interno di un array di oggetti, dove ogni oggetto ha sorgente e nodi di destinazione, coordinate x, y.

Quando si effettua il salvataggio, è sufficiente fare JSON.stringify(whole_object) e, se si carica, semplicemente JSON.parse() e posizionare manualmente i nodi e collegarli.

+0

puoi condividere qualche codice? Sono confuso su come caricarli e collegarli. –

+0

Oh .. È stato molto tempo fa, ma per quanto mi ricordo semplicemente salvare i dati da JSON.stringify (objectCollection). Ci sono relazioni, posizioni, ecc. Ora quando vuoi caricare, fai JSON.parse (generateStrnig) e poi passa manualmente attraverso ciascun nodo nell'oggetto e posizionalo (con CSS) e collegali (con l'API jsPlumb). Scusa non ricordo esattamente :) –

0

Sto usando YUI con esso. Sto salvando la posizione di ogni oggetto della scatola connesso in una tabella. Io ho una tabella separata che memorizza una relazione genitore-figlio tra gli elementi, che è usata per determinare le linee che jsPlumb dovrebbe disegnare. Lo stabilisco utilizzando un processo di selezione in cui il primo elemento selezionato è il genitore e tutti gli altri elementi sono figli. Quando viene cliccato il pulsante "connetti", la selezione genitore/figlio delle voci viene cancellata. Lo faccio anche se fai clic sul genitore selezionato: cancella anche le selezioni secondarie.

2

Recentemente ho scritto questo post del blog sul perché jsPlumb non dispone di una funzione di salvataggio (e che vi consiglio di fare):

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

... forse qualcuno lo troverà utile.

+6

Ciò che le persone cercano è un modo semplice per dire: mantenere questo diagramma su xml/json, o salvarlo in un altro modo che può essere facilmente analizzato e mappato per aggiornare il modello di dati ... Sembra che sia un'ovvietà ovvia. Sembra che quello che hai delineato qui mi faccia prendere molti fastidiosi passaggi extra per arrivarci nel modo in cui voglio arrivare. –

+0

Il link è morto ... –

7

La mia soluzione salvare e caricare 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 Demo: http://jsfiddle.net/Rra6Y/137/

Nota: se demo non funziona in JsFiddle, assicurarsi che punta a un collegamento jsPlumb esistente (i link sono elencati in "Risorse esterne" voce di menu JsFiddle

+0

Ciao e grazie per questi suggerimenti. Cerco solo di creare un designer di macchine a stati finiti online con jsplumb e di salvare/caricare correttamente, ho bisogno di passare più dati rispetto all'html che hai aggiunto al mio array. Qualcosa come "nome dello stato", "connesso" e così via. Sai, qualcosa per salvare effettivamente la mia "macchina di stato", non solo il mio "disegno". Hai un suggerimento su come farlo, forse? sarebbe bello! – Dominik

+0

il collegamento jsfiddle non funziona. Impossibile trascinare e non vengono create connessioni. Ci sono errori nella console per salvare, caricare e cancellare. –

3

La mia funzione di salvataggio fa un po 'di più che salvare la posizione x, y dell'elemento e le sue connessioni.Ho aggiunto anche una sovrapposizione di etichette di connessione e testo personalizzato per ogni elemento. yo u può adattare questa soluzione secondo le vostre esigenze, ma qui è fondamentalmente:

//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; 
    } 

Io inizio tutto questo quando l'utente preme il pulsante di salvataggio, una chiamata AJAX viene effettuata al server, in questo caso Django sta intercettando la richiesta Ajax e salva i dati nel database.

// chiamata AJAX quando pulsante Salva premuto $ 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? 

});

Per caricare tutto questo è ancora più semplice e ci sono molti modi per farlo. In Django puoi solo generare il codice html direttamente nel tuo modello e il js per le connessioni oppure puoi creare un oggetto JSON in javascript per ogni cosa e poi fare in modo che javascript lo disegni in base all'array. Ho usato jquery per questo.

//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 %} 

È possibile semplificare notevolmente questo ma miniera ottiene anche uno sfondo per l'elemento, così come etichetta e la forma dell'elemento da utilizzare con tasselli perimetrali. Questa soluzione funziona ed è testata. Pubblicherò presto un'applicazione Djago open source su PyPi.

Problemi correlati