Смежные svg: края многоугольника не встречаются

Я рисую гистограмму, используя многоугольники рядом друг с другом, например:

Если вы посмотрите внимательно, между каждым многоугольником (увеличенным) есть пробелы:

Я пытаюсь предотвратить это. Я узнал SVG shape-rendering и установил его в geometricPrecision. Это решило проблему, но дало мне очень четкие края:

Я тоже этого не хочу. Я пробовал другие возможные значения для shape-rendering, но никто не работал хорошо. (Я пробовал их на WebKit.) Я ищу решение.

Для интересующихся, jsFiddle диаграммы здесь.

Ответ 1

В действительности проблема заключается в том, что вы должны показывать граф как один многоугольник, а не один полигон для каждого бара, но я предполагаю, что есть причина, по которой вы это делаете.

Одним из возможных решений является установка свойств штриха, поэтому контур многоугольников нарисован, что приводит к их небольшому перекрытию. Вы можете установить эти свойства в элементе группы, чтобы применить их ко всем замкнутым многоугольникам.

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

Обновлена ​​ссылка jsFiddle

Обратите внимание, что это делает график немного большим, чем должно быть, но я не думаю, что это значительная проблема.

Что касается причины, по которой это происходит, это связано с тем, что смещения ваших полигонов точно не выравниваются по границам пикселей (по крайней мере, в большинстве случаев). Если вы установили ширину svg на кратное 300 пикселей (таким образом, выровняв все на границах пикселей), пробелы должны исчезнуть.

Рассмотрим пиксельную область 4x4, где вы пытаетесь отобразить квадрат от (0,0) до (2.5,2.5) следующим образом:

enter image description here

Вы можете нарисовать пиксели от (0,0) до (1,1) в сплошном черном, но как вы справляетесь с краями - они не полностью черные и полностью белые. Решение сглаживания должно использовать оттенок серого, пропорциональный размеру пикселя.

enter image description here

Но тогда, когда вы пытаетесь сделать другой полигон рядом с первым (т.е. начиная со смещения 2,5), у вас будет такая же проблема, как сглаживание левого края. Только на этот раз будет немного темнее, так как фон серый, а не белый.

enter image description here

Как вы нашли, вы можете отключить этот эффект, установив другой вариант рендеринга фигуры, но затем вы теряете преимущество сглаживания на наклонных линиях, делая эти края зазубренными.

Ответ 2

Я нашел окончательное и элегантное решение этой проблемы. Преобразуйте несколько полигонов в путь с несколькими сегментами:

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

Однако это не сработает, если вы хотите применить различные эффекты к каждому сегменту. В этом случае обходной путь, я думаю, будет заключаться в том, чтобы добавить штрих, достаточно широкий, чтобы покрыть белые пространства, сохраняя AA.

Кроме того, у меня все еще были проблемы с Safari (только) относительно порядка точек в разных полигонах. Изменение порядка (т.е. По часовой стрелке против часовой стрелки) устранило проблему.