Интернет

Разработка гибких и поддерживаемых круговых диаграмм с помощью CSS и SVG. Как быстро построить круговую диаграмму на CSS и JavaScript

Разработка гибких и поддерживаемых круговых диаграмм с помощью CSS и SVG. Как быстро построить круговую диаграмму на CSS и JavaScript

Для front-end разработчика существует огромное количество способов, которыми можно построить круговую диаграмму -  разнообразные библиотеки, плагины, потрясающие возможности SVG графики и т.д. Однако стоит, пожалуй, рассмотреть и самый простой способ создания «пирожкового» чарта, который может быть полезен, когда задача поставлена максимально просто и нет необходимости или возможности использовать дополнительные инструменты. Далее речь пойдёт о примере такой реализации.

Предположим, что имеются исходные данные в виде такого массива, которые нужно представить на круговой диаграмме:

Var dataset = [ { value: 5, color: "#dc3912" }, { value: 40, color: "#ff9900" }, { value: 30, color: "#109618" }, { value: 25, color: "#990099" } ];

value -  это значение в процентах, color -  цвет сектора.

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

Зададим ему также стили:

Container { width: 300px; height: 300px; overflow: hidden; border-radius: 50%; position: relative; }

В результате получаем такой круг. Всё, что выходит за пределы его границ (изображены пунктиром) будет скрыто.

Далее закономерно возникает вопрос -  как мы превратим прямоугольные элементы div в секторы круга и как зададим им нужный угол? Собственно, для первой цели и было установлено свойство overflow:hidden контейнеру, т.к. это позволяет скрыть часть элемента, сделав его таким образом округлым, а для второй нам помогут CSS-трансформации. Далее на примере для одного сектора.

Добавим внутрь контейнера div с классом sector.

CSS:

Sector { width: 50%; height: 50%; position: absolute; left: 50%; top: 0; transform-origin: left bottom; background: #000; }

Таким образом, получился сектор со значением 90 градусов, начинающийся на отметке в 0 градусов.

Для того, чтобы задать нужный угол этому сектору, применим CSS-трансформацию skewY. Эта трансформация сдвигает правое ребро квадрата по оси y так, чтобы горизонтальные рёбра образовывали заданный угол со своим исходным положением:

Значение value в первом элементе массива dataset равно 5, переводя в градусы, получаем 18. Для того, чтобы наклон происходил в нужную сторону, ко всем углам будем добавлять 90 градусов.

Таким образом, угол трансформации = 90 + 18 = 108.

transform: skewY(108deg);

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

Transform: rotate(45deg) skewY(108deg);

У этого способа есть один недостаток -  как видно на рисунке, иллюстрирующем значения трансформации skewY, таким образом можно корректно изображать сектора со значением не более 90 градусов. Поэтому для изображения значений, больших, чем 90, придётся рисовать несколько секторов одинакового цвета. Например, если значение угла 100 градусов, отобразим 2 сектора: 90 градусов и 10. Если значение равно 200 градусам, получится 3 сектора -  по 90, 90 и 20 градусов и т.д.

В результате получаем следующий код для динамического добавления секторов:

Var maxValue = 25; var container = $(".container"); var addSector = function(data, startAngle, collapse) { var sectorDeg = 3.6 * data.value; var skewDeg = 90 + sectorDeg; var rotateDeg = startAngle; if (collapse) { skewDeg++; } var sector = $("", { "class": "sector" }).css({ "background": data.color, "transform": "rotate(" + rotateDeg + "deg) skewY(" + skewDeg + "deg)" }); container.append(sector); return startAngle + sectorDeg; }; dataset.reduce(function (prev, curr) { return (function addPart(data, angle) { if (data.value