2014-06-18 15 views
22

Sto giocando con un gradiente di gradazione SVG come modo per "troncare" le stringhe di testo lungo in un grafico d3.js.SVG: perché i CSS esterni sovrascrivono lo stile in linea per il testo?

Sembra che uno stile css esterno per il riempimento sovrascriva lo stile di riempimento sfumato in linea in SVG ... è sempre così? Come posso applicare il riempimento sfumato?

In questo caso di test ho definito un gradiente lineare nelle svg defs e quindi si applica il riempimento del gradiente a due gruppi di testo. http://jsfiddle.net/rolfsf/uX2kH/3/

var labelColWidth = 200; 
var svg = d3.select('#test').append('svg') 
      .attr('width', 500) 
      .attr('height', 500); 

var defs = svg.append('svg:defs'); 

var textgradient = defs.append('svg:linearGradient') 
      .attr('gradientUnits', 'userSpaceOnUse') 
      .attr('x1', 0).attr('y1', 0).attr('x2', 40).attr('y2', 0) 
      .attr('id', 'theGradient') 
      .attr('gradientTransform', 'translate(' + (labelColWidth - 40) + ')'); 

    textgradient.append('svg:stop').attr('offset', '0%').attr('style', 'stop-color:rgb(0,0,0);stop-opacity:1') 
    textgradient.append('svg:stop').attr('offset', '100%').attr('style', 'stop-color:rgb(0,0,0);stop-opacity:0'); 


var data = [[0, "xyzzy xyzzy"], [1, "xyzzy xyzzy xyzzy xyzzy xyzzy"], [2, "xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy"], [3, "xyzzy xyzzy xyzzy"], [4, "xyzzy xyzzy"], [5, "xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy xyzzy"]]; 

var testGroup = svg.append('g') 
    .attr('transform', 'translate(50, 100)'); 

var testGroup2 = svg.append('g') 
    .attr('transform', 'translate(50, 250)') 
    .attr('class', 'group2'); 

testGroup.selectAll('text').data(data) 
    .enter().append('svg:text') 
    .attr('fill', 'url(#theGradient)') 
    .attr('x', 0) 
    .attr('y', function(d, i) { return (i+1) * 20; }) 
    .text(function(d, i) { return d[1]; }); 

testGroup2.selectAll('text').data(data) 
    .enter().append('svg:text') 
    .attr('fill', 'url(#theGradient)') 
    .attr('x', 0) 
    .attr('y', function(d, i) { return (i+1) * 20; }) 
    .text(function(d, i) { return d[1]; }); 

poi nel CSS, definisco un riempimento per il testo .group2

.group2 text { 
    fill: #000; 
} 

il primo gruppo ha il riempimento sfumato, il secondo gruppo non lo fa.

Non dovrebbe lo stile in linea avere la precedenza?

Grazie!

risposta

28

Perché in SVG, come HTML prima, gli stili superano lo stile degli attributi.

fill="red" di seguito non è un "stile in linea", style="fill:green"IS uno stile in linea.

<svg width="400" height="400"> 
 
    <text x="50" y="50" fill="red" style="fill:green">This will be green</text> 
 
</svg>

Come saggio, se si dispone di uno stile definito al di fuori, si vincerà.

<style> 
 
    text { fill: lime; } 
 
</style>
<svg width="300" height="300"> 
 
    <text x="50" y="40" fill="red">This will be lime</text> 
 
</svg>

+0

Hmmm ...quindi, come si applica un riempimento sfumato che sostituisce qualsiasi riempimento di testo predefinito? – rolfsf

+0

'style =" fill: url (#myGradientId) "' dovrebbe fare il trucco. –

7

Dal SVG specification

Per utente che supportano CSS, gli attributi di presentazione devono essere tradotti in corrispondenti regole di stile CSS secondo regole descritte in precedenza di non-CSS suggerimenti di presentazione ([CSS2], sezione 6.4.4), con l'ulteriore chiarimento che gli attributi di presentazione sono concettualmente inseriti in un nuovo foglio di stile dell'autore che è il primo nello stile dell'autore collezione et. Gli attributi di presentazione quindi parteciperanno alla cascata CSS2 come se fossero sostituiti dalle corrispondenti regole di stile CSS posizionate all'inizio del foglio di stile dell'autore con una specificità pari a zero. In generale, ciò significa che gli attributi di presentazione hanno una priorità inferiore a rispetto ad altre regole di stile CSS specificate nei fogli di stile dell'autore o negli attributi di "stile".

Quindi è possibile utilizzare uno stile in linea anziché un attributo di presentazione, ad es.

.attr('style', 'fill : url(#theGradient)') 
+0

Grazie - ha funzionato in questo fiddle aggiornato: http://jsfiddle.net/rolfsf/uX2kH/4/ – rolfsf

0

Nel mio caso è stato così semplice come la sostituzione attr con style nella catena d3:

.style('stroke', 'url(#gradient--min)') 
Problemi correlati