Snap.svg предоставляет удобные инструменты для создания векторной графики на веб-странице, включая построение круговых диаграмм. Круговая диаграмма состоит из сегментов (секторов), которые визуально отображают пропорции данных.
Для начала необходимо создать контейнер SVG с помощью Snap:
var s = Snap(500, 500); // создаём холст размером 500x500 пикселей
Контейнер s станет основой для всех элементов
диаграммы.
Круговой сегмент строится с помощью команды path.
Основная идея — использовать дугу (arc) для формирования
части окружности. Для этого удобно определить функцию, которая строит
путь сегмента:
function describeArc(x, y, radius, startAngle, endAngle){
var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);
var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
return [
"M", start.x, start.y,
"A", radius, radius, 0, largeArcFlag, 0, end.x, end.y,
"L", x, y,
"Z"
].join(" ");
}
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}
polarToCartesian переводит угол в координаты точки на
окружности.describeArc возвращает строку пути, формирующую
сектор.После определения функции построения пути можно добавить сегменты диаграммы:
var data = [30, 70, 45, 55]; // значения для диаграммы
var colors = ["#FF5733", "#33FF57", "#3357FF", "#F3FF33"];
var total = data.reduce((a,b) => a + b, 0);
var startAngle = 0;
data.forEach(function(value, i){
var angle = (value / total) * 360;
var path = describeArc(250, 250, 100, startAngle, startAngle + angle);
s.path(path).attr({fill: colors[i]});
startAngle += angle;
});
data.reduce вычисляет общую сумму значений для
корректного расчёта углов.startAngle аккумулирует начальный угол для каждого
нового сегмента.fill задаёт цвет сегмента.Snap.svg позволяет анимировать сегменты. Для плавного отображения
можно использовать изменение атрибута path:
var pathElement = s.path(describeArc(250, 250, 100, 0, 0)).attr({fill: "#FF5733"});
pathElement.animate({d: describeArc(250, 250, 100, 0, 120)}, 1000, mina.easeinout);
animate плавно меняет атрибут d пути.mina.easeinout добавляет эффект замедления в начале и
конце анимации.Для отображения значений можно использовать элемент
text:
var angle = 60; // средний угол сегмента
var pos = polarToCartesian(250, 250, 70, angle); // позиция текста внутри сегмента
s.text(pos.x, pos.y, "30").attr({
"font-size": 16,
"text-anchor": "middle",
"alignment-baseline": "middle"
});
text-anchor: middle центрирует текст по
горизонтали.alignment-baseline: middle центрирует по вертикали
относительно заданной точки.Snap.svg позволяет добавлять события для сегментов:
pathElement.hover(
function(){ this.attr({fill: "#FF0000"}); },
function(){ this.attr({fill: "#FF5733"}); }
);
hover принимает функции для наведения мыши и её
ухода.polarToCartesian и
describeArc.Использование Snap.svg для круговых диаграмм обеспечивает точное построение сегментов, гибкость при изменении данных и возможность визуально насыщенных эффектов без сторонних библиотек.