Как нарисовать кольцевую диаграмму с закругленными углами и разными градиентами и тенями в каждом сегменте
Мне необходимо реализовать кольцевую диаграмму как на изображении ниже:
Возникает несколько проблем:
- Каждый сегмент окрашен в свой градиент
- Сегменты имеют закругленные края
- Каждый сегмент может быть использован в дальнейшем, как ссылка
Конечно можно решить эти вопросы в векторном редакторе, создав для каждого сегмента свой path, но такое решение трудоемко и нужно будет каждый раз перерисовывать, если количество сегментов будет изменено и/или будет изменен их размер.
Стандартное решение, разбить окружность на сектора с помощью stroke-dasharray, не подойдет, так как все сегменты при этом решении, будут окрашены в один цвет;
Вот примерный код, но он не решает проблемы:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" style="border:1px solid" >
<circle id="s2" cx="200" cy="200" r="160" fill="none" stroke="#FAE094" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5" />
<polyline points="200,0 200,400" fill="none" stroke="black" />
<polyline points="0,200 400,200" fill="none" stroke="black" />
</svg>
- Как сделать сегменты разной длины?
- Как закрасить их разными градиентами?
- Как сделать закругленные края для каждого сегмента.
Примечание.
Атрибут stroke-lineCap="round" не подойдет, так как полностью закруглит края, а нужно, как на рисунке, совсем немного закруглить.
Ответы (1 шт):
Чтобы каждый сегмент был самостоятельным для принятия своего градиента и в последствии мог бы быть использован, как отдельная ссылка, вместо одной окружности будем использовать четыре окружности, так как на диаграмме 4 сектора.
На каждой окружности будет выводиться только один сектор, а через пробелы будет видна вторая окружность со своим одним сектором и т.д.
#1. Пример окружности с одним сектором:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" style="border:1px solid" >
<circle id="s2" transform="rotate(-120 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FAE094" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<polyline points="200,0 200,400" fill="none" stroke="black" />
<polyline points="0,200 400,200" fill="none" stroke="black" />
</svg>
#2. Добавляем остальные окружности со своими секторами
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" style="border:1px solid" >
<circle id="s1" transform="rotate(-120 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FAE094" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s2" transform="rotate(-58 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FCF0D0" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s3" transform="rotate(5 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="335, 670" />
<circle id="s4" transform="rotate(137 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="296, 695" />
<polyline points="200,0 200,400" fill="none" stroke="black" />
<polyline points="0,200 400,200" fill="none" stroke="black" />
</svg>
#3. Делаем закругленные уголки у секторов
Для этого используем SVG filter:
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix"
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
<style>
circle{
filter:url(#goo);
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" style="border:1px solid" >
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
<circle id="s1" transform="rotate(-120 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FAE094" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s2" transform="rotate(-58 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FCF0D0" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s3" transform="rotate(5 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="335, 670" />
<circle id="s4" transform="rotate(137 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="296, 695" />
</svg>
#4. Добавляем радиальные градиенты
Каждому сектору свой градиент:
circle{
filter:url(#goo);
}
#s1 {
stroke:url(#rg1);
}
#s2 {
stroke:url(#rg2);
}
#s3 {
stroke:url(#rg3);
}
#s4 {
stroke:url(#rg4);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" >
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
<radialGradient id="rg1" r="1" fx="0.6" fy="0.5">
<stop offset="40%" stop-color="#F6BD4A"></stop>
<stop offset="50%" stop-color="#F6DFB2"></stop>
<stop offset="70%" stop-color="white"></stop>
<stop offset="90%" stop-color="#F6AC17"></stop>
</radialGradient>
<radialGradient id="rg2" r="1" fx="0.4" fy="0.5">
<stop offset="40%" stop-color="#F6BD4A"></stop>
<stop offset="50%" stop-color="#F6DFB2"></stop>
<stop offset="70%" stop-color="white"></stop>
<stop offset="90%" stop-color="#F6AC17"></stop>
</radialGradient>
<radialGradient id="rg3" r="1" fx="0.5" fy="0.5">
<stop offset="40%" stop-color="#DCDCDC"></stop>
<stop offset="50%" stop-color="#FFFFFF"></stop>
<stop offset="60%" stop-color="#CDCDCD"></stop>
<stop offset="90%" stop-color="#CDCDCD"></stop>
</radialGradient>
<radialGradient id="rg4" r="1" fx="0.5" fy="0.5">
<stop offset="40%" stop-color="#DCDCDC"></stop>
<stop offset="50%" stop-color="#F3F3F3"></stop>
<stop offset="60%" stop-color="#B8B8B8"></stop>
<stop offset="90%" stop-color="#B8B8B8"></stop>
</radialGradient>
</defs>
<circle id="s1" transform="rotate(-120 200 200)" cx="200" cy="200" r="160" fill="none" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s2" transform="rotate(-58 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FCF0D0" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
<circle id="s3" transform="rotate(5 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="335, 670" />
<circle id="s4" transform="rotate(137 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="296, 695" />
</svg>
UPDATE
<style>
circle{
filter:url(#goo);
}
#s1 {
stroke:url(#rg1);
}
#s2 {
stroke:url(#rg2);
}
#s3 {
stroke:url(#rg3);
}
#s4 {
stroke:url(#rg4);
}
</style>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="400" height="400" viewBox="0 0 400 400" >
<defs>
<filter id="goo"><feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
<radialGradient id="rg1" r="1" fx="0.6" fy="0.5">
<stop offset="40%" stop-color="#F6BD4A"></stop>
<stop offset="50%" stop-color="#F6DFB2"></stop>
<stop offset="70%" stop-color="white"></stop>
<stop offset="90%" stop-color="#F6AC17"></stop>
</radialGradient>
<radialGradient id="rg2" r="1" fx="0.4" fy="0.5">
<stop offset="40%" stop-color="#F6BD4A"></stop>
<stop offset="50%" stop-color="#F6DFB2"></stop>
<stop offset="70%" stop-color="white"></stop>
<stop offset="90%" stop-color="#F6AC17"></stop>
</radialGradient>
<radialGradient id="rg3" r="1" fx="0.5" fy="0.5">
<stop offset="40%" stop-color="#DCDCDC"></stop>
<stop offset="50%" stop-color="#FFFFFF"></stop>
<stop offset="60%" stop-color="#CDCDCD"></stop>
<stop offset="90%" stop-color="#CDCDCD"></stop>
</radialGradient>
<radialGradient id="rg4" r="1" fx="0.5" fy="0.5">
<stop offset="40%" stop-color="#DCDCDC"></stop>
<stop offset="50%" stop-color="#F3F3F3"></stop>
<stop offset="60%" stop-color="#B8B8B8"></stop>
<stop offset="90%" stop-color="#B8B8B8"></stop>
</radialGradient>
</defs>
<a href="https://ru.stackoverflow.com/questions/tagged/svg">
<title>Вопросы с меткой [SVG]</title>
<circle id="s1" transform="rotate(-120 200 200)" cx="200" cy="200" r="160" fill="none" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
</a>
<a href="https://ru.stackoverflow.com/questions/tagged/css">
<title>Вопросы с меткой [CSS]</title>
<circle id="s2" transform="rotate(-58 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#FCF0D0" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="167.5, 837.7" />
</a>
<a href="https://ru.stackoverflow.com/questions/tagged/javascript">
<title>Вопросы с меткой [Javascript]</title>
<circle id="s3" transform="rotate(5 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="335, 670" />
</a>
<a href="https://ru.stackoverflow.com/questions/tagged/python">
<title>Вопросы с меткой [python]</title>
<circle id="s4" transform="rotate(137 200 200)" cx="200" cy="200" r="160" fill="none" stroke="#C4C4C4" stroke-width="50" stroke-dashoffset="1005.2" stroke-dasharray="296, 695" />
</svg>
</a>
#5. Вариант с всплывающими подсказками при наведении и переходом по ссылке при клике
