2013-07-24 15 views
10

sto disegnando un grafico a barre utilizzando poligoni uno accanto all'altro in questo modo:Adiacente svg: bordi dei poligoni non soddisfano

Se si guarda da vicino, ci sono spazi bianchi tra ogni poligono (zoom) :

sto cercando di evitare che ciò accada. Ho scoperto l'attributo SVG shape-rendering e l'ho impostato su geometricPrecision. Questo ha risolto il problema, ma mi ha dato molto bordi nitidi:

non voglio nemmeno questo. Ho provato altri possibili valori per shape-rendering ma nessuno ha funzionato bene. (Ho provato questi su WebKit.) Sto cercando una soluzione.

Per chi è interessato, jsFiddle del grafico here.

+0

Grazie per l'uomo di punta 'shape-rendering'! Esattamente quello che stavo cercando. Qualcosa che l'articolo collegato non ha notato è che puoi anche usarlo su gruppi all'interno di SVG, il che è molto utile se hai forme geometriche e contorni di testo (che tu * fai * vuoi essere anti-alias) combinati. – Rijk

risposta

7

In realtà il problema è che si dovrebbe rappresentare il grafico come un singolo poligono piuttosto che un poligono per ogni barra, ma suppongo che ci sia un motivo per cui lo si sta facendo in questo modo.

Una possibile soluzione consiste nell'impostare le proprietà del tratto, in modo da disegnare il contorno dei poligoni, in modo che si sovrappongano leggermente. È possibile impostare tali proprietà sull'elemento del gruppo per applicarle a tutti i poligoni racchiusi.

<g stroke-width="0.5" stroke="black" stroke-linejoin="round"> 

Updated jsFiddle link

Si noti che questo rende il grafico un aspetto leggermente biggger di quanto dovrebbe essere, ma non credo che sia un problema significativo.

Per quanto riguarda il motivo per cui sta accadendo, è perché gli offset dei poligoni non sono esattamente allineati sui limiti dei pixel (almeno la maggior parte delle volte). Se hai corretto la larghezza dello svg su un multiplo di 300 px (allineando tutto su limiti di pixel) gli spazi dovrebbero andare via.

consideri un'area di 4x4 pixel, in cui si sta cercando di rendere un quadrato da (0,0) a (2.5,2.5) come questo:

enter image description here

Si può dipingere i pixel da (0 , Da 0) a (1,1) in nero pieno, ma come si gestiscono i bordi: non sono né completamente neri né completamente bianchi. La soluzione anti-aliasing consiste nell'utilizzare una tonalità di grigio proporzionale alla quantità di pixel coperta.

enter image description here

Ma poi quando si cerca di rendere un altro poligono proprio accanto alla prima (vale a dire a partire da un offset di 2.5), che si sta per avere lo stesso problema anti-aliasing il bordo sinistro. Solo che questa volta sarà leggermente più scura poiché lo sfondo è grigio anziché bianco.

enter image description here

Come hai trovato, è possibile disattivare questo effetto impostando una diversa forma-rendering opzione , ma poi si perde il beneficio di anti-aliasing su linee inclinate, rendendo i bordi ondeggiano .

+0

Sì, in realtà stavo progettando di aggiungere un effetto hover sui poligoni, ecco perché li ho separati in primo luogo invece di un singolo grande poligono. Penso che questo farà il trucco. Ma perché sta succedendo questo, puoi rispondere a questo? –

+1

@ahmetalpbalkan Ho aggiornato la mia risposta con una spiegazione del perché stai vedendo queste lacune. –

+0

Ma se il grigio era assolutamente proporzionale, sarebbe grigio al 50%. Due grigi del 50% dovrebbero combinarsi per ottenere un nero al 100%. Mi sembra che la maggior parte dei renderer siano effettivamente antialias rispetto allo sfondo dell'oggetto SVG piuttosto che a ciò che è attualmente sul canvas SVG. O quello, o le tecniche di antialiasing non sono perfette e non producono il 50% di grigio per un bordo a x + 0,5 pixel. – trlkly

0

Ho trovato una soluzione definitiva ed elegante per questo problema. Convertire i più poligoni in un percorso con più segmenti:

<script src="http://d3js.org/d3.v3.min.js"></script> 
<svg width="100%" height="30%" viewBox="0 0 100 100" preserveAspectRatio="none"> 
     <path d="M0,100 0,70 3.3333333333333335,66 3.3333333333333335,100 M3.3333333333333335,100 3.3333333333333335,66 6.666666666666667,66 6.666666666666667,100 M6.666666666666667,100 6.666666666666667,66 10,62 10,100 M10,100 10,62 13.333333333333334,57.99999999999999 13.333333333333334,100 M13.333333333333334,100 13.333333333333334,57.99999999999999 16.666666666666664,56 16.666666666666664,100 M16.666666666666664,100 16.666666666666664,56 20,54 20,100 M20,100 20,54 23.333333333333332,40 23.333333333333332,100 M23.333333333333332,100 23.333333333333332,40 26.666666666666668,24 26.666666666666668,100 M26.666666666666668,100 26.666666666666668,24 30,15.999999999999998 30,100 M30,100 30,15.999999999999998 33.33333333333333,13.999999999999996 33.33333333333333,100 M33.33333333333333,100 33.33333333333333,13.999999999999996 36.666666666666664,11.999999999999996 36.666666666666664,100 M36.666666666666664,100 36.666666666666664,11.999999999999996 40,10.000000000000004 40,100 M40,100 40,10.000000000000004 43.333333333333336,10.000000000000004 43.333333333333336,100 M43.333333333333336,100 43.333333333333336,10.000000000000004 46.666666666666664,8.000000000000004 46.666666666666664,100 M46.666666666666664,100 46.666666666666664,8.000000000000004 50,8.000000000000004 50,100 M50,100 50,8.000000000000004 53.333333333333336,6.000000000000002 53.333333333333336,100 M53.333333333333336,100 53.333333333333336,6.000000000000002 56.666666666666664,6.000000000000002 56.666666666666664,100 M56.666666666666664,100 56.666666666666664,6.000000000000002 60,8.000000000000004 60,100 M60,100 60,8.000000000000004 63.33333333333333,10.000000000000004 63.33333333333333,100 M63.33333333333333,100 63.33333333333333,10.000000000000004 66.66666666666666,8.000000000000004 66.66666666666666,100 M66.66666666666666,100 66.66666666666666,8.000000000000004 70,11.999999999999996 70,100 M70,100 70,11.999999999999996 73.33333333333333,13.999999999999996 73.33333333333333,100 M73.33333333333333,100 73.33333333333333,13.999999999999996 76.66666666666667,11.999999999999996 76.66666666666667,100 M76.66666666666667,100 76.66666666666667,11.999999999999996 80,10.000000000000004 80,100 M80,100 80,10.000000000000004 83.33333333333334,11.999999999999996 83.33333333333334,100 M83.33333333333334,100 83.33333333333334,11.999999999999996 86.66666666666667,13.999999999999996 86.66666666666667,100 M86.66666666666667,100 86.66666666666667,13.999999999999996 90,11.999999999999996 90,100 M90,100 90,11.999999999999996 93.33333333333333,4.000000000000002 93.33333333333333,100 M93.33333333333333,100 93.33333333333333,4.000000000000002 96.66666666666667,0 96.66666666666667,100 M96.66666666666667,100 96.66666666666667,0 100,0 100,100 M100,100 100,0 100,0 100,100"/> 
</svg> 

http://jsfiddle.net/313xc6bg/

Non funzionerà se si desidera applicare effetti diversi a ciascun segmenti però. In questo caso, penso che la soluzione sarebbe quella di aggiungere un tratto abbastanza ampio da coprire gli spazi bianchi mantenendo l'AA acceso.

Inoltre, ho ancora avuto problemi con Safari (solo) rispetto all'ordine dei punti in diversi poligoni. Cambiando l'ordine (cioè in senso orario in senso antiorario) risolto il problema.