2013-06-13 7 views
7

Assegnare attributi artificiali a un elemento SVG-G (oggetto gruppo SVG). Sposto il gruppo con il suo contenuto con le trasformazioni SVG e memorizzo le coordinate x/y del gruppo e la sua larghezza/altezza in quegli attributi.È possibile impostare gli attributi personalizzati degli oggetti SVG come numero e non come stringa?

Sto usando la biblioteca D3 Javascript e la chiamata:

embeddedElemContainer = nodeBoxContainer.append('svg:g') 
    .attr('x', x) 
    .attr('y', y) 
    .attr('width', width) 
    .attr('height', height) 

risultati in seguente oggetto:

<g transform="translate(13.585786437626904,31.585786437626904)" x="13.585786437626904" y="31.585786437626904" width="43.00000000000001" height="0"></g> 

Questa è Ok, l'unico ting mi dà fastidio è il fatto, che l'attributo i valori sono memorizzati come stringa. Se voglio usarli per qualche calcolo, sono costretto a trasmettere.

parseInt(@embeddedElemContainer.attr('x')) 

C'è un modo per memorizzare i valori direttamente come interi/raddoppiare?

risposta

5

L'approccio normale in D3 è quello di disporre di elenchi di dati associati ai nodi. Vedi lo data portion of the Selection API. D3 lo inserisce nella proprietà __data__ dei nodi DOM che crea/modifica. Internamente D3 estrae quella proprietà e la trasmette come parametro a varie funzioni, ma puoi certamente accedervi direttamente.

È inoltre possibile associare una struttura dati arbitraria a un nodo singolo tramite lo Datum method.

senza il resto del contesto è difficile da dire, ma sotto è una versione modificata di quello che penso che si sta cercando di fare:

var vis = d3.select("body").append("svg").attr("width", 400).attr("height", 300); 

var groupData = {x: 100, y:100, height: 50, width: 50, theanswer : 42, thecolor: "blue", somedouble: 45.1651654 }; 

var embeddedElemContainer = vis.append('svg:g') 
    .datum(groupData) 
    .attr('id', 'mygroup') 
    .attr('x', function(d) { return d.x; }) 
    .attr('y', function(d) { return d.y; }) 
    .attr('height', function(d) { return d.height; }) 
    .attr('width', function(d) { return d.width; }) 

// the regular DOM way: 
console.log(document.getElementById('mygroup').__data__) 

// the D3 way: 
console.log(d3.select('#mygroup').datum()); 

Sia uscita console.log dichiarazioni:

height: 50 
somedouble: 45.1651654 
theanswer: 42 
thecolor: "blue" 
width: 50 
x: 100 
y: 100 
+0

OH! Molte grazie per la tua grande spiegazione. Devo leggere di più sui dati/attributi di delimitazione sugli elementi in D3. Non ho mai pensato di utilizzare questa funzionalità per i miei scopi. – karlitos

0

È possibile ignorare la funzione attr di d3 per annusare i numeri e fare il parseInt per voi. Questo potrebbe presentare problemi di compatibilità più tardi, quindi forse sarebbe meglio creare una nuova funzione attrInt, ad esempio:

d3.selection.prototype.attrInt = function(name, value) { 
    if(arguments.length == 1) { 
    return parseInt(this.attr(name)); 
    } else { 
    return this.attr(name, value); 
    } 
}; 

Disclaimer: non ho esperienza con d3 quindi non sono sicuro se questo è il prototipo corretto da allegare a; L'ho appena preso dal dare un'occhiata alla fonte. :)

+0

Mentre questo potrebbe funzionare, penso che D3 abbia un approccio integrato più pulito per questo. Vedi la mia risposta. – explunit